Skip to content

Releases: binacle-labs/Binacle.Net

v3.0.0

Choose a tag to compare

@github-actions github-actions released this 01 Sep 20:18
150b61e

Binacle.Net v3.0.0 is 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 strings from earlier versions no longer decode, and health check IP restrictions are matched differently.


🔎 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. Strings from earlier versions no longer decode.
  • ViPaq left experimental status — the format is stable as of this release.
  • 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 demo UI was rebuilt, its page addresses changed, and it gained a page describing the instance you are on.
  • The image creates /app/data and gives it to the app user, so a volume mounted there is writable.
  • The image is signed, and carries an SBOM and build provenance, so you can verify what you pull.
  • The image is about a third smaller — it uses the .NET runtime from its base image instead of bundling a second copy.
  • 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.
  • The project moved to the binacle-labs organization. Links redirect; the signing identity does not.
  • Licensing is now stated per part. The samples, the build tooling, the Ruby gems and the ViPaq and compact notation libraries are permissive, so they can be copied without taking on the code licence. The documentation moved from CC BY-SA 4.0 to CC BY 4.0, which drops the ShareAlike condition on quoting it.
  • The code licence changed from GPL-3.0 to AGPL-3.0. Run the image as it ships and there is nothing to do. Change it and run it as a service for other people, and you publish what you changed. The permissive parts stay permissive. Versions up to and including 3.0.0-beta.6 remain under GPL-3.0, and that text is kept at LICENSE.GPL-3.0/.

⚙️ 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 answerfit/bin, pack/bin, and their {preset}/{bin} variants.

  • Many bins, one answerpack/smallest-bin, pack/smallest-bin/{preset}, fit/smallest-bin, and fit/smallest-bin/{preset} return the smallest bin that works; pack/best-bin and pack/best-bin/{preset} return the bin the items fill the most.

  • Many bins, every answerfit/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 presets or fetched one at a time with presets/{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.

  • A non-string algorithm value now answers 422 rather than 400. "algorithm": 1, true or a list used to come back as Invalid JSON Format with no field named. It now comes back as a validation error naming the field — the same answer a misspelled name such as "FFDD" has always given. Both statuses were already declared on these endpoints, so the contract has not moved; what changed is which one you get.

  • ViPaq is no longer experimental. The format is settled as of this release, where it carried an experimental warning through v2.1.1. A future format change takes a new Version code rather than altering the current one, so an older decoder rejects a newer string outright instead of misreading it.

  • 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-For and X-Forwarded-Proto before 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_ENABLED is ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.

  • TrustedProxies entries are read exactly as written, the same rule as health check RestrictedIPs. 010.10.10.10 used to be read as octal and trust 8.10.10.10, and 172.17.1 used to mean 172.17.0.1; both now fail startup validation rather than trusting a host you did not name.

  • Added a /_debug endpoint, off by default, enabled with DEBUG_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.

  • No Strict-Transport-Security header is sent. The UseHsts call arrived with the demo UI's template and only ever ran when that UI was on. The image terminates no TLS, so the proxy or CDN in front of it is the only thing that knows whether HSTS is safe to pin, and a browser honours it until it expires.

  • The image now creates /app/data and gives it to the app user. A volume mounted there is writable with no extra setup. Previously docker created the mount point as root, the app does not run as root, and packing logs and the SQLite database could not be written to a fresh named volume.

  • The image ships libgssapi-krb5-2, so Npgsql stops printing Cannot load library libgssapi_krb5.so.2 at every start. Nothing was broken — the app authenticates with a password, not Kerberos — but the message read like a fatal error.

  • The image carries OCI labels — title, description, source, url, documentation, vendor, licence and base image — plus version, revision and created per build.

  • The description at the top of every API document changed. The same one-line summary now appears in Swagger UI, Scalar and the image's description label.

  • The image is signed, and ships an SBOM and build provenance. Signing is keyless, so there is no public key to fetch — the signature is checked against the workflow that produced it — and it covers the digest, so it holds for every tag pointing at that image:

    cosign verify binacle/binacle-net:3.0.0 \
      --certificate-identity-regexp '^https://github\.com/binacle-labs/Binacle\.Net/\.github/workflows/release-docker-image\.yml@refs/heads/main$' \
      --certificate-oidc-issuer https://token.actions.githubusercontent.com

    The SPDX SBOM and SLSA provenance travel inside the image index; docker buildx imagetools inspect binacle/binacle-net:3.0.0 lists them.

  • The project moved to the binacle-labs organization, and the signing identity moved with it. The command above names the new organization. GitHub redirects a moved repository's links, but a certificate identity is written into the signature and does not redirect — a stale one fails the check rather than warning.

  • The image is smaller — 100 to 110 MB, where the same image built the old way was 150 to 160 MB. The app is published framework-dependent, so it runs on the .NET runtime already in the aspnet:10.0 base image instead of carrying a second copy of it. Nothing about running the container changes.

  • One environment variable was removed — BINACLEAPI_CONNECTION_STRING. The UI module used it to point the demo at another API host. The rebuilt module reads no configuration and always calls the API it is served from, so the variable is now ignored rather than rejected. Config_Files/UiModule/ConnectionStrings.json went with it, and the image no longer ships a UiModule config folder.

  • Every other environment variable is unchanged.

🧪 Diagnostics Module

  • Packing Logs configuration was flattenedPath, FileName, DateFormat, and ChannelLimit now sit directly under PackingLogs.
  • 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/ to data/pack-logs/.
  • Packing log entries now include a Timestamp field.
  • Added RetentionDays to PackingLogs. When set, packing log files older than that many days are deleted once a day, and each deletion is logged. Off by default (null) — files are kept until you remove them yourself. Only files matching the configured FileName pattern in the configured Path are touched, and only at the top level.
  • /_health now reports what the instance is running. Its System entry carried only Processors. It now also carries Version, Environment, StartedAt and Uptime, plus Features — the names of everything switched on, such as HealthChecks, UIModule or SwaggerUI — and `ReservedPat...
Read more

v3.0.0-beta.8

v3.0.0-beta.8 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Sep 19:47
955ec0b

Binacle.Net v3.0.0 is 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 strings from earlier versions no longer decode, and health check IP restrictions are matched differently.


🔎 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. Strings from earlier versions no longer decode.
  • ViPaq left experimental status — the format is stable as of this release.
  • 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 demo UI was rebuilt, its page addresses changed, and it gained a page describing the instance you are on.
  • The image creates /app/data and gives it to the app user, so a volume mounted there is writable.
  • The image is signed, and carries an SBOM and build provenance, so you can verify what you pull.
  • The image is about a third smaller — it uses the .NET runtime from its base image instead of bundling a second copy.
  • 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.
  • The project moved to the binacle-labs organization. Links redirect; the signing identity does not.
  • Licensing is now stated per part. The samples, the build tooling, the Ruby gems and the ViPaq and compact notation libraries are permissive, so they can be copied without taking on the code licence. The documentation moved from CC BY-SA 4.0 to CC BY 4.0, which drops the ShareAlike condition on quoting it.
  • The code licence changed from GPL-3.0 to AGPL-3.0. Run the image as it ships and there is nothing to do. Change it and run it as a service for other people, and you publish what you changed. The permissive parts stay permissive. Versions up to and including 3.0.0-beta.6 remain under GPL-3.0, and that text is kept at LICENSE.GPL-3.0/.

⚙️ 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 answerfit/bin, pack/bin, and their {preset}/{bin} variants.

  • Many bins, one answerpack/smallest-bin, pack/smallest-bin/{preset}, fit/smallest-bin, and fit/smallest-bin/{preset} return the smallest bin that works; pack/best-bin and pack/best-bin/{preset} return the bin the items fill the most.

  • Many bins, every answerfit/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 presets or fetched one at a time with presets/{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.

  • A non-string algorithm value now answers 422 rather than 400. "algorithm": 1, true or a list used to come back as Invalid JSON Format with no field named. It now comes back as a validation error naming the field — the same answer a misspelled name such as "FFDD" has always given. Both statuses were already declared on these endpoints, so the contract has not moved; what changed is which one you get.

  • ViPaq is no longer experimental. The format is settled as of this release, where it carried an experimental warning through v2.1.1. A future format change takes a new Version code rather than altering the current one, so an older decoder rejects a newer string outright instead of misreading it.

  • 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-For and X-Forwarded-Proto before 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_ENABLED is ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.

  • TrustedProxies entries are read exactly as written, the same rule as health check RestrictedIPs. 010.10.10.10 used to be read as octal and trust 8.10.10.10, and 172.17.1 used to mean 172.17.0.1; both now fail startup validation rather than trusting a host you did not name.

  • Added a /_debug endpoint, off by default, enabled with DEBUG_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.

  • No Strict-Transport-Security header is sent. The UseHsts call arrived with the demo UI's template and only ever ran when that UI was on. The image terminates no TLS, so the proxy or CDN in front of it is the only thing that knows whether HSTS is safe to pin, and a browser honours it until it expires.

  • The image now creates /app/data and gives it to the app user. A volume mounted there is writable with no extra setup. Previously docker created the mount point as root, the app does not run as root, and packing logs and the SQLite database could not be written to a fresh named volume.

  • The image ships libgssapi-krb5-2, so Npgsql stops printing Cannot load library libgssapi_krb5.so.2 at every start. Nothing was broken — the app authenticates with a password, not Kerberos — but the message read like a fatal error.

  • The image carries OCI labels — title, description, source, url, documentation, vendor, licence and base image — plus version, revision and created per build.

  • The description at the top of every API document changed. The same one-line summary now appears in Swagger UI, Scalar and the image's description label.

  • The image is signed, and ships an SBOM and build provenance. Signing is keyless, so there is no public key to fetch — the signature is checked against the workflow that produced it — and it covers the digest, so it holds for every tag pointing at that image:

    cosign verify binacle/binacle-net:3.0.0 \
      --certificate-identity-regexp '^https://github\.com/binacle-labs/Binacle\.Net/\.github/workflows/release-docker-image\.yml@refs/heads/main$' \
      --certificate-oidc-issuer https://token.actions.githubusercontent.com

    The SPDX SBOM and SLSA provenance travel inside the image index; docker buildx imagetools inspect binacle/binacle-net:3.0.0 lists them.

  • The project moved to the binacle-labs organization, and the signing identity moved with it. The command above names the new organization. GitHub redirects a moved repository's links, but a certificate identity is written into the signature and does not redirect — a stale one fails the check rather than warning.

  • The image is smaller — around 108 MB, where the same image built the old way was 158 MB. The app is published framework-dependent, so it runs on the .NET runtime already in the aspnet:10.0 base image instead of carrying a second copy of it. Nothing about running the container changes.

  • One environment variable was removed — BINACLEAPI_CONNECTION_STRING. The UI module used it to point the demo at another API host. The rebuilt module reads no configuration and always calls the API it is served from, so the variable is now ignored rather than rejected. Config_Files/UiModule/ConnectionStrings.json went with it, and the image no longer ships a UiModule config folder.

  • Every other environment variable is unchanged.

🧪 Diagnostics Module

  • Packing Logs configuration was flattenedPath, FileName, DateFormat, and ChannelLimit now sit directly under PackingLogs.
  • 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/ to data/pack-logs/.
  • Packing log entries now include a Timestamp field.
  • Added RetentionDays to PackingLogs. When set, packing log files older than that many days are deleted once a day, and each deletion is logged. Off by default (null) — files are kept until you remove them yourself. Only files matching the configured FileName pattern in the configured Path are touched, and only at the top level.
  • /_health now reports what the instance is running. Its System entry carried only Processors. It now also carries Version, Environment, StartedAt and Uptime, plus Features — the names of everything switched on, such as HealthChecks, UIModule or SwaggerUI — and ReservedPaths, th...
Read more

v3.0.0-beta.7

v3.0.0-beta.7 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 31 Aug 08:49

Binacle.Net v3.0.0 is 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 strings from earlier versions no longer decode, and health check IP restrictions are matched differently.


🔎 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. Strings from earlier versions no longer decode.
  • ViPaq left experimental status — the format is stable as of this release.
  • 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 demo UI was rebuilt, its page addresses changed, and it gained a page describing the instance you are on.
  • The image creates /app/data and gives it to the app user, so a volume mounted there is writable.
  • The image is signed, and carries an SBOM and build provenance, so you can verify what you pull.
  • The image is about a third smaller — it uses the .NET runtime from its base image instead of bundling a second copy.
  • 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.
  • The project moved to the binacle-labs organization. Links redirect; the signing identity does not.
  • Licensing is now stated per part. The samples, the build tooling, the Ruby gems and the ViPaq and compact notation libraries are permissive, so they can be copied without taking on the code licence. The documentation moved from CC BY-SA 4.0 to CC BY 4.0, which drops the ShareAlike condition on quoting it.
  • The code licence changed from GPL-3.0 to AGPL-3.0. Run the image as it ships and there is nothing to do. Change it and run it as a service for other people, and you publish what you changed. The permissive parts stay permissive. Versions up to and including 3.0.0-beta.6 remain under GPL-3.0, and that text is kept at LICENSE.GPL-3.0/.

⚙️ 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 answerfit/bin, pack/bin, and their {preset}/{bin} variants.

  • Many bins, one answerpack/smallest-bin, pack/smallest-bin/{preset}, fit/smallest-bin, and fit/smallest-bin/{preset} return the smallest bin that works; pack/best-bin and pack/best-bin/{preset} return the bin the items fill the most.

  • Many bins, every answerfit/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 presets or fetched one at a time with presets/{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.

  • A non-string algorithm value now answers 422 rather than 400. "algorithm": 1, true or a list used to come back as Invalid JSON Format with no field named. It now comes back as a validation error naming the field — the same answer a misspelled name such as "FFDD" has always given. Both statuses were already declared on these endpoints, so the contract has not moved; what changed is which one you get.

  • ViPaq is no longer experimental. The format is settled as of this release, where it carried an experimental warning through v2.1.1. A future format change takes a new Version code rather than altering the current one, so an older decoder rejects a newer string outright instead of misreading it.

  • 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-For and X-Forwarded-Proto before 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_ENABLED is ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.

  • TrustedProxies entries are read exactly as written, the same rule as health check RestrictedIPs. 010.10.10.10 used to be read as octal and trust 8.10.10.10, and 172.17.1 used to mean 172.17.0.1; both now fail startup validation rather than trusting a host you did not name.

  • Added a /_debug endpoint, off by default, enabled with DEBUG_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.

  • No Strict-Transport-Security header is sent. The UseHsts call arrived with the demo UI's template and only ever ran when that UI was on. The image terminates no TLS, so the proxy or CDN in front of it is the only thing that knows whether HSTS is safe to pin, and a browser honours it until it expires.

  • The image now creates /app/data and gives it to the app user. A volume mounted there is writable with no extra setup. Previously docker created the mount point as root, the app does not run as root, and packing logs and the SQLite database could not be written to a fresh named volume.

  • The image ships libgssapi-krb5-2, so Npgsql stops printing Cannot load library libgssapi_krb5.so.2 at every start. Nothing was broken — the app authenticates with a password, not Kerberos — but the message read like a fatal error.

  • The image carries OCI labels — title, description, source, url, documentation, vendor, licence and base image — plus version, revision and created per build.

  • The description at the top of every API document changed. The same one-line summary now appears in Swagger UI, Scalar and the image's description label.

  • The image is signed, and ships an SBOM and build provenance. Signing is keyless, so there is no public key to fetch — the signature is checked against the workflow that produced it — and it covers the digest, so it holds for every tag pointing at that image:

    cosign verify binacle/binacle-net:3.0.0 \
      --certificate-identity-regexp '^https://github\.com/binacle-labs/Binacle\.Net/\.github/workflows/release-docker-image\.yml@refs/heads/main$' \
      --certificate-oidc-issuer https://token.actions.githubusercontent.com

    The SPDX SBOM and SLSA provenance travel inside the image index; docker buildx imagetools inspect binacle/binacle-net:3.0.0 lists them.

  • The project moved to the binacle-labs organization, and the signing identity moved with it. The command above names the new organization. GitHub redirects a moved repository's links, but a certificate identity is written into the signature and does not redirect — a stale one fails the check rather than warning.

  • The image is smaller — around 108 MB, where the same image built the old way was 158 MB. The app is published framework-dependent, so it runs on the .NET runtime already in the aspnet:10.0 base image instead of carrying a second copy of it. Nothing about running the container changes.

  • One environment variable was removed — BINACLEAPI_CONNECTION_STRING. The UI module used it to point the demo at another API host. The rebuilt module reads no configuration and always calls the API it is served from, so the variable is now ignored rather than rejected. Config_Files/UiModule/ConnectionStrings.json went with it, and the image no longer ships a UiModule config folder.

  • Every other environment variable is unchanged.

🧪 Diagnostics Module

  • Packing Logs configuration was flattenedPath, FileName, DateFormat, and ChannelLimit now sit directly under PackingLogs.
  • 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/ to data/pack-logs/.
  • Packing log entries now include a Timestamp field.
  • Added RetentionDays to PackingLogs. When set, packing log files older than that many days are deleted once a day, and each deletion is logged. Off by default (null) — files are kept until you remove them yourself. Only files matching the configured FileName pattern in the configured Path are touched, and only at the top level.
  • /_health now reports what the instance is running. Its System entry carried only Processors. It now also carries Version, Environment, StartedAt and Uptime, plus Features — the names of everything switched on, such as HealthChecks, UIModule or SwaggerUI — and ReservedPaths, th...
Read more

v3.0.0-beta.6

v3.0.0-beta.6 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 30 Aug 23:01

Binacle.Net v3.0.0 is 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 strings from earlier versions no longer decode, and health check IP restrictions are matched differently.


🔎 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. Strings from earlier versions no longer decode.
  • ViPaq left experimental status — the format is stable as of this release.
  • 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 demo UI was rebuilt, its page addresses changed, and it gained a page describing the instance you are on.
  • The image creates /app/data and gives it to the app user, so a volume mounted there is writable.
  • The image is signed, and carries an SBOM and build provenance, so you can verify what you pull.
  • The image is about a third smaller — it uses the .NET runtime from its base image instead of bundling a second copy.
  • 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.
  • The project moved to the binacle-labs organization. Links redirect; the signing identity does not.
  • Licensing is now stated per part. The samples, the build tooling, the Ruby gems and the ViPaq and compact notation libraries are permissive, so they can be copied without taking on the code licence. The code stays GPL-3.0. The documentation moved from CC BY-SA 4.0 to CC BY 4.0, which drops the ShareAlike condition on quoting it.

⚙️ 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 answerfit/bin, pack/bin, and their {preset}/{bin} variants.

  • Many bins, one answerpack/smallest-bin, pack/smallest-bin/{preset}, fit/smallest-bin, and fit/smallest-bin/{preset} return the smallest bin that works; pack/best-bin and pack/best-bin/{preset} return the bin the items fill the most.

  • Many bins, every answerfit/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 presets or fetched one at a time with presets/{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.

  • A non-string algorithm value now answers 422 rather than 400. "algorithm": 1, true or a list used to come back as Invalid JSON Format with no field named. It now comes back as a validation error naming the field — the same answer a misspelled name such as "FFDD" has always given. Both statuses were already declared on these endpoints, so the contract has not moved; what changed is which one you get.

  • ViPaq is no longer experimental. The format is settled as of this release, where it carried an experimental warning through v2.1.1. A future format change takes a new Version code rather than altering the current one, so an older decoder rejects a newer string outright instead of misreading it.

  • 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-For and X-Forwarded-Proto before 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_ENABLED is ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.

  • TrustedProxies entries are read exactly as written, the same rule as health check RestrictedIPs. 010.10.10.10 used to be read as octal and trust 8.10.10.10, and 172.17.1 used to mean 172.17.0.1; both now fail startup validation rather than trusting a host you did not name.

  • Added a /_debug endpoint, off by default, enabled with DEBUG_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.

  • No Strict-Transport-Security header is sent. The UseHsts call arrived with the demo UI's template and only ever ran when that UI was on. The image terminates no TLS, so the proxy or CDN in front of it is the only thing that knows whether HSTS is safe to pin, and a browser honours it until it expires.

  • The image now creates /app/data and gives it to the app user. A volume mounted there is writable with no extra setup. Previously docker created the mount point as root, the app does not run as root, and packing logs and the SQLite database could not be written to a fresh named volume.

  • The image ships libgssapi-krb5-2, so Npgsql stops printing Cannot load library libgssapi_krb5.so.2 at every start. Nothing was broken — the app authenticates with a password, not Kerberos — but the message read like a fatal error.

  • The image carries OCI labels — title, description, source, url, documentation, vendor, licence and base image — plus version, revision and created per build.

  • The description at the top of every API document changed. The same one-line summary now appears in Swagger UI, Scalar and the image's description label.

  • The image is signed, and ships an SBOM and build provenance. Signing is keyless, so there is no public key to fetch — the signature is checked against the workflow that produced it — and it covers the digest, so it holds for every tag pointing at that image:

    cosign verify binacle/binacle-net:3.0.0 \
      --certificate-identity-regexp '^https://github\.com/binacle-labs/Binacle\.Net/\.github/workflows/release-docker-image\.yml@refs/heads/main$' \
      --certificate-oidc-issuer https://token.actions.githubusercontent.com

    The SPDX SBOM and SLSA provenance travel inside the image index; docker buildx imagetools inspect binacle/binacle-net:3.0.0 lists them.

  • The project moved to the binacle-labs organization, and the signing identity moved with it. The command above names the new organization. GitHub redirects a moved repository's links, but a certificate identity is written into the signature and does not redirect — a stale one fails the check rather than warning.

  • The image is smaller — around 108 MB, where the same image built the old way was 158 MB. The app is published framework-dependent, so it runs on the .NET runtime already in the aspnet:10.0 base image instead of carrying a second copy of it. Nothing about running the container changes.

  • One environment variable was removed — BINACLEAPI_CONNECTION_STRING. The UI module used it to point the demo at another API host. The rebuilt module reads no configuration and always calls the API it is served from, so the variable is now ignored rather than rejected. Config_Files/UiModule/ConnectionStrings.json went with it, and the image no longer ships a UiModule config folder.

  • Every other environment variable is unchanged.

🧪 Diagnostics Module

  • Packing Logs configuration was flattenedPath, FileName, DateFormat, and ChannelLimit now sit directly under PackingLogs.
  • 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/ to data/pack-logs/.
  • Packing log entries now include a Timestamp field.
  • Added RetentionDays to PackingLogs. When set, packing log files older than that many days are deleted once a day, and each deletion is logged. Off by default (null) — files are kept until you remove them yourself. Only files matching the configured FileName pattern in the configured Path are touched, and only at the top level.
  • /_health now reports what the instance is running. Its System entry carried only Processors. It now also carries Version, Environment, StartedAt and Uptime, plus Features — the names of everything switched on, such as HealthChecks, UIModule or SwaggerUI — and ReservedPaths, the path prefixes that never answer with a web page. Processors is unchanged, so an existing parser keeps working; the new keys are there to check that a configuration arrived the way you meant it to.
  • Health check RestrictedIPs now uses CIDR notation correctly. The value after / was previously read as an address mask, so 192.168.1.0/24 covered nearly the whole IPv4 range instead o...
Read more

v3.0.0-beta.5

v3.0.0-beta.5 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 27 Aug 23:44

Binacle.Net v3.0.0 is 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 strings from earlier versions no longer decode, and health check IP restrictions are matched differently.


🔎 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. Strings from earlier versions no longer decode.
  • ViPaq left experimental status — the format is stable as of this release.
  • 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 demo UI was rebuilt, its page addresses changed, and it gained a page describing the instance you are on.
  • The image creates /app/data and gives it to the app user, so a volume mounted there is writable.
  • The image is signed, and carries an SBOM and build provenance, so you can verify what you pull.
  • The image is about a third smaller — it uses the .NET runtime from its base image instead of bundling a second copy.
  • 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.
  • The project moved to the binacle-labs organization. Links redirect; the signing identity does not.

⚙️ 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 answerfit/bin, pack/bin, and their {preset}/{bin} variants.

  • Many bins, one answerpack/smallest-bin, pack/smallest-bin/{preset}, fit/smallest-bin, and fit/smallest-bin/{preset} return the smallest bin that works; pack/best-bin and pack/best-bin/{preset} return the bin the items fill the most.

  • Many bins, every answerfit/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 presets or fetched one at a time with presets/{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.

  • A non-string algorithm value now answers 422 rather than 400. "algorithm": 1, true or a list used to come back as Invalid JSON Format with no field named. It now comes back as a validation error naming the field — the same answer a misspelled name such as "FFDD" has always given. Both statuses were already declared on these endpoints, so the contract has not moved; what changed is which one you get.

  • ViPaq is no longer experimental. The format is settled as of this release, where it carried an experimental warning through v2.1.1. A future format change takes a new Version code rather than altering the current one, so an older decoder rejects a newer string outright instead of misreading it.

  • 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-For and X-Forwarded-Proto before 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_ENABLED is ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.

  • TrustedProxies entries are read exactly as written, the same rule as health check RestrictedIPs. 010.10.10.10 used to be read as octal and trust 8.10.10.10, and 172.17.1 used to mean 172.17.0.1; both now fail startup validation rather than trusting a host you did not name.

  • Added a /_debug endpoint, off by default, enabled with DEBUG_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.

  • No Strict-Transport-Security header is sent. The UseHsts call arrived with the demo UI's template and only ever ran when that UI was on. The image terminates no TLS, so the proxy or CDN in front of it is the only thing that knows whether HSTS is safe to pin, and a browser honours it until it expires.

  • The image now creates /app/data and gives it to the app user. A volume mounted there is writable with no extra setup. Previously docker created the mount point as root, the app does not run as root, and packing logs and the SQLite database could not be written to a fresh named volume.

  • The image ships libgssapi-krb5-2, so Npgsql stops printing Cannot load library libgssapi_krb5.so.2 at every start. Nothing was broken — the app authenticates with a password, not Kerberos — but the message read like a fatal error.

  • The image carries OCI labels — title, description, source, url, documentation, vendor, licence and base image — plus version, revision and created per build.

  • The description at the top of every API document changed. The same one-line summary now appears in Swagger UI, Scalar and the image's description label.

  • The image is signed, and ships an SBOM and build provenance. Signing is keyless, so there is no public key to fetch — the signature is checked against the workflow that produced it — and it covers the digest, so it holds for every tag pointing at that image:

    cosign verify binacle/binacle-net:3.0.0 \
      --certificate-identity-regexp '^https://github\.com/binacle-labs/Binacle\.Net/\.github/workflows/release-docker-image\.yml@' \
      --certificate-oidc-issuer https://token.actions.githubusercontent.com

    The SPDX SBOM and SLSA provenance travel inside the image index; docker buildx imagetools inspect binacle/binacle-net:3.0.0 lists them.

  • The project moved to the binacle-labs organization, and the signing identity moved with it. The command above names the new organization. GitHub redirects a moved repository's links, but a certificate identity is written into the signature and does not redirect — a stale one fails the check rather than warning.

  • The image is smaller — around 108 MB, where the same image built the old way was 158 MB. The app is published framework-dependent, so it runs on the .NET runtime already in the aspnet:10.0 base image instead of carrying a second copy of it. Nothing about running the container changes.

  • One environment variable was removed — BINACLEAPI_CONNECTION_STRING. The UI module used it to point the demo at another API host. The rebuilt module reads no configuration and always calls the API it is served from, so the variable is now ignored rather than rejected. Config_Files/UiModule/ConnectionStrings.json went with it, and the image no longer ships a UiModule config folder.

  • Every other environment variable is unchanged.

🧪 Diagnostics Module

  • Packing Logs configuration was flattenedPath, FileName, DateFormat, and ChannelLimit now sit directly under PackingLogs.
  • 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/ to data/pack-logs/.
  • Packing log entries now include a Timestamp field.
  • Added RetentionDays to PackingLogs. When set, packing log files older than that many days are deleted once a day, and each deletion is logged. Off by default (null) — files are kept until you remove them yourself. Only files matching the configured FileName pattern in the configured Path are touched, and only at the top level.
  • /_health now reports what the instance is running. Its System entry carried only Processors. It now also carries Version, Environment, StartedAt and Uptime, plus Features — the names of everything switched on, such as HealthChecks, UIModule or SwaggerUI — and ReservedPaths, the path prefixes that never answer with a web page. Processors is unchanged, so an existing parser keeps working; the new keys are there to check that a configuration arrived the way you meant it to.
  • Health check RestrictedIPs now uses CIDR notation correctly. The value after / was previously read as an address mask, so 192.168.1.0/24 covered nearly the whole IPv4 range instead of 256 addresses. Existing CIDR entries are now much narrower than they were.
  • Health check RestrictedIPs now 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-end range form from `RestrictedIP...
Read more

v3.0.0-beta.4

v3.0.0-beta.4 Pre-release
Pre-release

Choose a tag to compare

@ChrisMavrommatis ChrisMavrommatis released this 19 Aug 07:58

Binacle.Net v3.0.0 is 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 strings from earlier versions no longer decode, and health check IP restrictions are matched differently.


🔎 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. Strings from earlier versions no longer decode.
  • ViPaq left experimental status — the format is stable as of this release.
  • 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 image creates /app/data and gives it to the app user, so a volume mounted there is writable.
  • The image is signed, and carries an SBOM and build provenance, so you can verify what you pull.
  • The image is about a third smaller — it uses the .NET runtime from its base image instead of bundling a second copy.
  • 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.
  • The project moved to the binacle-labs organization. Links redirect; the signing identity does not.

⚙️ 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 answerfit/bin, pack/bin, and their {preset}/{bin} variants.

  • Many bins, one answerpack/smallest-bin, pack/smallest-bin/{preset}, fit/smallest-bin, and fit/smallest-bin/{preset} return the smallest bin that works; pack/best-bin and pack/best-bin/{preset} return the bin the items fill the most.

  • Many bins, every answerfit/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 presets or fetched one at a time with presets/{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.

  • ViPaq is no longer experimental. The format is settled as of this release, where it carried an experimental warning through v2.1.1. A future format change takes a new Version code rather than altering the current one, so an older decoder rejects a newer string outright instead of misreading it.

  • 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-For and X-Forwarded-Proto before 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_ENABLED is ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.

  • TrustedProxies entries are read exactly as written, the same rule as health check RestrictedIPs. 010.10.10.10 used to be read as octal and trust 8.10.10.10, and 172.17.1 used to mean 172.17.0.1; both now fail startup validation rather than trusting a host you did not name.

  • Added a /_debug endpoint, off by default, enabled with DEBUG_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.

  • The image now creates /app/data and gives it to the app user. A volume mounted there is writable with no extra setup. Previously docker created the mount point as root, the app does not run as root, and packing logs and the SQLite database could not be written to a fresh named volume.

  • The image ships libgssapi-krb5-2, so Npgsql stops printing Cannot load library libgssapi_krb5.so.2 at every start. Nothing was broken — the app authenticates with a password, not Kerberos — but the message read like a fatal error.

  • The image carries OCI labels — title, description, source, url, documentation, vendor, licence and base image — plus version, revision and created per build.

  • The image is signed, and ships an SBOM and build provenance. Signing is keyless, so there is no public key to fetch — the signature is checked against the workflow that produced it — and it covers the digest, so it holds for every tag pointing at that image:

    cosign verify binacle/binacle-net:3.0.0 \
      --certificate-identity-regexp '^https://github\.com/binacle-labs/Binacle\.Net/\.github/workflows/release-docker-image\.yml@' \
      --certificate-oidc-issuer https://token.actions.githubusercontent.com

    The SPDX SBOM and SLSA provenance travel inside the image index; docker buildx imagetools inspect binacle/binacle-net:3.0.0 lists them.

  • The project moved to the binacle-labs organization, and the signing identity moved with it. The command above names the new organization. GitHub redirects a moved repository's links, but a certificate identity is written into the signature and does not redirect — a stale one fails the check rather than warning.

  • The image is smaller — around 103 MB, where the same image built the old way was 150 MB. The app is published framework-dependent, so it runs on the .NET runtime already in the aspnet:10.0 base image instead of carrying a second copy of it. Nothing about running the container changes.

  • Existing environment variables are unchanged.

🧪 Diagnostics Module

  • Packing Logs configuration was flattenedPath, FileName, DateFormat, and ChannelLimit now sit directly under PackingLogs.
  • 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/ to data/pack-logs/.
  • Packing log entries now include a Timestamp field.
  • Added RetentionDays to PackingLogs. When set, packing log files older than that many days are deleted once a day, and each deletion is logged. Off by default (null) — files are kept until you remove them yourself. Only files matching the configured FileName pattern in the configured Path are touched, and only at the top level.
  • Health check RestrictedIPs now uses CIDR notation correctly. The value after / was previously read as an address mask, so 192.168.1.0/24 covered nearly the whole IPv4 range instead of 256 addresses. Existing CIDR entries are now much narrower than they were.
  • Health check RestrictedIPs now 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-end range form from RestrictedIPs. Entries such as 192.168.1.0-192.168.1.255 now fail startup validation. Use CIDR instead.
  • RestrictedIPs entries 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.10 used to be read as octal and admit 8.10.10.10; 10.1 used to mean 10.0.0.1; 167772161 meant the same. All of these now fail startup validation instead of quietly admitting a host you did not name. 192.168.1.1/24 still means the whole 192.168.1.0/24 — that is what CIDR notation means — but the startup log now says so.

🔌 Service Module

  • The Service Module is exempt from these notes — since v2.0.0 it is developed for the hosted service, so a change to it is not documented here and does not force a major version. If you self-host with SERVICE_MODULE enabled, read the full changelog before upgrading. One fix is worth calling out on its own:
  • The auth token rate limit no longer partitions on a caller-supplied header. It partitions on the connection's remote address, which forwarded headers resolve to the real caller wherever a proxy is trusted. Before this, varying the header reset your own login throttle.

🎨 UI Module

  • The Protocol Decoder reads the new ViPaq format only. Strings 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.
  • Ad...
Read more

v3.0.0-beta.3

v3.0.0-beta.3 Pre-release
Pre-release

Choose a tag to compare

@ChrisMavrommatis ChrisMavrommatis released this 16 Aug 20:27

Binacle.Net v3.0.0 is 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 strings from earlier versions no longer decode, and health check IP restrictions are matched differently.


🔎 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. Strings from earlier versions no longer decode.
  • ViPaq left experimental status — the format is stable as of this release.
  • 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 image creates /app/data and gives it to the app user, so a volume mounted there is writable.
  • The image is signed, and carries an SBOM and build provenance, so you can verify what you pull.
  • The image is about a third smaller — it uses the .NET runtime from its base image instead of bundling a second copy.
  • 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.
  • The project moved to the binacle-labs organization. Links redirect; the signing identity does not.

⚙️ 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 answerfit/bin, pack/bin, and their {preset}/{bin} variants.

  • Many bins, one answerpack/smallest-bin, pack/smallest-bin/{preset}, fit/smallest-bin, and fit/smallest-bin/{preset} return the smallest bin that works; pack/best-bin and pack/best-bin/{preset} return the bin the items fill the most.

  • Many bins, every answerfit/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 presets or fetched one at a time with presets/{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.

  • ViPaq is no longer experimental. The format is settled as of this release, where it carried an experimental warning through v2.1.1. A future format change takes a new Version code rather than altering the current one, so an older decoder rejects a newer string outright instead of misreading it.

  • 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-For and X-Forwarded-Proto before 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_ENABLED is ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.

  • TrustedProxies entries are read exactly as written, the same rule as health check RestrictedIPs. 010.10.10.10 used to be read as octal and trust 8.10.10.10, and 172.17.1 used to mean 172.17.0.1; both now fail startup validation rather than trusting a host you did not name.

  • Added a /_debug endpoint, off by default, enabled with DEBUG_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.

  • The image now creates /app/data and gives it to the app user. A volume mounted there is writable with no extra setup. Previously docker created the mount point as root, the app does not run as root, and packing logs and the SQLite database could not be written to a fresh named volume.

  • The image ships libgssapi-krb5-2, so Npgsql stops printing Cannot load library libgssapi_krb5.so.2 at every start. Nothing was broken — the app authenticates with a password, not Kerberos — but the message read like a fatal error.

  • The image carries OCI labels — title, description, source, url, documentation, vendor, licence and base image — plus version, revision and created per build.

  • The image is signed, and ships an SBOM and build provenance. Signing is keyless, so there is no public key to fetch — the signature is checked against the workflow that produced it — and it covers the digest, so it holds for every tag pointing at that image:

    cosign verify binacle/binacle-net:3.0.0 \
      --certificate-identity-regexp '^https://github\.com/binacle-labs/Binacle\.Net/\.github/workflows/release-docker-image\.yml@' \
      --certificate-oidc-issuer https://token.actions.githubusercontent.com

    The SPDX SBOM and SLSA provenance travel inside the image index; docker buildx imagetools inspect binacle/binacle-net:3.0.0 lists them.

  • The project moved to the binacle-labs organization, and the signing identity moved with it. The command above names the new organization. GitHub redirects a moved repository's links, but a certificate identity is written into the signature and does not redirect — a stale one fails the check rather than warning. 3.0.0-beta.2 is the one published image signed under the old identity, and verifies only with ChrisMavrommatis in that flag.

  • The image is smaller — around 103 MB, where the same image built the old way was 150 MB. The app is published framework-dependent, so it runs on the .NET runtime already in the aspnet:10.0 base image instead of carrying a second copy of it. Nothing about running the container changes.

  • Existing environment variables are unchanged.

🧪 Diagnostics Module

  • Packing Logs configuration was flattenedPath, FileName, DateFormat, and ChannelLimit now sit directly under PackingLogs.
  • 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/ to data/pack-logs/.
  • Packing log entries now include a Timestamp field.
  • Added RetentionDays to PackingLogs. When set, packing log files older than that many days are deleted once a day, and each deletion is logged. Off by default (null) — files are kept until you remove them yourself. Only files matching the configured FileName pattern in the configured Path are touched, and only at the top level.
  • Health check RestrictedIPs now uses CIDR notation correctly. The value after / was previously read as an address mask, so 192.168.1.0/24 covered nearly the whole IPv4 range instead of 256 addresses. Existing CIDR entries are now much narrower than they were.
  • Health check RestrictedIPs now 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-end range form from RestrictedIPs. Entries such as 192.168.1.0-192.168.1.255 now fail startup validation. Use CIDR instead.
  • RestrictedIPs entries 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.10 used to be read as octal and admit 8.10.10.10; 10.1 used to mean 10.0.0.1; 167772161 meant the same. All of these now fail startup validation instead of quietly admitting a host you did not name. 192.168.1.1/24 still means the whole 192.168.1.0/24 — that is what CIDR notation means — but the startup log now says so.

🔌 Service Module

  • The Service Module is exempt from these notes — since v2.0.0 it is developed for the hosted service, so a change to it is not documented here and does not force a major version. If you self-host with SERVICE_MODULE enabled, read the full changelog before upgrading. One fix is worth calling out on its own:
  • The auth token rate limit no longer partitions on a caller-supplied header. It partitions on the connection's remote address, which forwarded headers resolve to the real caller wherever a proxy is trusted. Before this, varying the header reset your own login throttle.

🎨 UI Module

  • The Protocol Decoder reads the new ViPaq format only. Strings 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 *...
Read more

v3.0.0-beta.2

v3.0.0-beta.2 Pre-release
Pre-release

Choose a tag to compare

@ChrisMavrommatis ChrisMavrommatis released this 13 Aug 19:59

Binacle.Net v3.0.0 is 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 strings from earlier versions no longer decode, and health check IP restrictions are matched differently.


🔎 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. Strings from earlier versions no longer decode.
  • ViPaq left experimental status — the format is stable as of this release.
  • 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 image creates /app/data and gives it to the app user, so a volume mounted there is writable.
  • The image is signed, and carries an SBOM and build provenance, so you can verify what you pull.
  • The image is about a third smaller — it uses the .NET runtime from its base image instead of bundling a second copy.
  • 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 answerfit/bin, pack/bin, and their {preset}/{bin} variants.

  • Many bins, one answerpack/smallest-bin, pack/smallest-bin/{preset}, fit/smallest-bin, and fit/smallest-bin/{preset} return the smallest bin that works; pack/best-bin and pack/best-bin/{preset} return the bin the items fill the most.

  • Many bins, every answerfit/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 presets or fetched one at a time with presets/{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.

  • ViPaq is no longer experimental. The format is settled as of this release, where it carried an experimental warning through v2.1.1. A future format change takes a new Version code rather than altering the current one, so an older decoder rejects a newer string outright instead of misreading it.

  • 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-For and X-Forwarded-Proto before 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_ENABLED is ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.

  • TrustedProxies entries are read exactly as written, the same rule as health check RestrictedIPs. 010.10.10.10 used to be read as octal and trust 8.10.10.10, and 172.17.1 used to mean 172.17.0.1; both now fail startup validation rather than trusting a host you did not name.

  • Added a /_debug endpoint, off by default, enabled with DEBUG_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.

  • The image now creates /app/data and gives it to the app user. A volume mounted there is writable with no extra setup. Previously docker created the mount point as root, the app does not run as root, and packing logs and the SQLite database could not be written to a fresh named volume.

  • The image ships libgssapi-krb5-2, so Npgsql stops printing Cannot load library libgssapi_krb5.so.2 at every start. Nothing was broken — the app authenticates with a password, not Kerberos — but the message read like a fatal error.

  • The image carries OCI labels — title, description, source, url, documentation, vendor, licence and base image — plus version, revision and created per build.

  • The image is signed, and ships an SBOM and build provenance. Signing is keyless, so there is no public key to fetch — the signature is checked against the workflow that produced it — and it covers the digest, so it holds for every tag pointing at that image:

    cosign verify binacle/binacle-net:3.0.0 \
      --certificate-identity-regexp '^https://github\.com/ChrisMavrommatis/Binacle\.Net/\.github/workflows/release-docker-image\.yml@' \
      --certificate-oidc-issuer https://token.actions.githubusercontent.com

    The SPDX SBOM and SLSA provenance travel inside the image index; docker buildx imagetools inspect binacle/binacle-net:3.0.0 lists them.

  • The image is smaller — around 103 MB, where the same image built the old way was 150 MB. The app is published framework-dependent, so it runs on the .NET runtime already in the aspnet:10.0 base image instead of carrying a second copy of it. Nothing about running the container changes.

  • Existing environment variables are unchanged.

🧪 Diagnostics Module

  • Packing Logs configuration was flattenedPath, FileName, DateFormat, and ChannelLimit now sit directly under PackingLogs.
  • 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/ to data/pack-logs/.
  • Packing log entries now include a Timestamp field.
  • Added RetentionDays to PackingLogs. When set, packing log files older than that many days are deleted once a day, and each deletion is logged. Off by default (null) — files are kept until you remove them yourself. Only files matching the configured FileName pattern in the configured Path are touched, and only at the top level.
  • Health check RestrictedIPs now uses CIDR notation correctly. The value after / was previously read as an address mask, so 192.168.1.0/24 covered nearly the whole IPv4 range instead of 256 addresses. Existing CIDR entries are now much narrower than they were.
  • Health check RestrictedIPs now 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-end range form from RestrictedIPs. Entries such as 192.168.1.0-192.168.1.255 now fail startup validation. Use CIDR instead.
  • RestrictedIPs entries 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.10 used to be read as octal and admit 8.10.10.10; 10.1 used to mean 10.0.0.1; 167772161 meant the same. All of these now fail startup validation instead of quietly admitting a host you did not name. 192.168.1.1/24 still means the whole 192.168.1.0/24 — that is what CIDR notation means — but the startup log now says so.

🔌 Service Module

  • The Service Module is exempt from these notes — since v2.0.0 it is developed for the hosted service, so a change to it is not documented here and does not force a major version. If you self-host with SERVICE_MODULE enabled, read the full changelog before upgrading. One fix is worth calling out on its own:
  • The auth token rate limit no longer partitions on a caller-supplied header. It partitions on the connection's remote address, which forwarded headers resolve to the real caller wherever a proxy is trusted. Before this, varying the header reset your own login throttle.

🎨 UI Module

  • The Protocol Decoder reads the new ViPaq format only. Strings 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.OpenApi and the bundled SQLite native library.
  • Rebuilt the release pipeline. A tag now builds the image once, stages it on GHCR, smoke tests it there, then copies the tested di...
Read more

v3.0.0-beta.1

v3.0.0-beta.1 Pre-release
Pre-release

Choose a tag to compare

@ChrisMavrommatis ChrisMavrommatis released this 30 Jul 20:53
8f511dd

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 answerfit/bin, pack/bin, and their {preset}/{bin} variants.
  • Many bins, one answerpack/smallest-bin, pack/smallest-bin/{preset}, fit/smallest-bin, and fit/smallest-bin/{preset} return the smallest bin that works; pack/best-bin and pack/best-bin/{preset} return the bin the items fill the most.
  • Many bins, every answerfit/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 presets or fetched one at a time with presets/{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-For and X-Forwarded-Proto before 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_ENABLED is ignored. It switches the underlying middleware on with no proxy verification, which lets any caller choose their own address.
  • TrustedProxies entries are read exactly as written, the same rule as health check RestrictedIPs. 010.10.10.10 used to be read as octal and trust 8.10.10.10, and 172.17.1 used to mean 172.17.0.1; both now fail startup validation rather than trusting a host you did not name.
  • Added a /_debug endpoint, off by default, enabled with DEBUG_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_ENDPOINT is the only new one.
  • The image now creates /app/data and 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 printed Cannot load library libgssapi_krb5.so.2 at 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 inspect describe it.

🧪 Diagnostics Module

  • Packing Logs configuration was flattenedPath, FileName, DateFormat, and ChannelLimit now sit directly under PackingLogs.
  • 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/ to data/pack-logs/.
  • Packing log entries now include a Timestamp field.
  • Added an optional RetentionDays under PackingLogs. Log files older than that are deleted once a day. Unset by default, which keeps every file — deletion stays opt-in.
  • Health check RestrictedIPs now uses CIDR notation correctly. The value after / was previously read as an address mask, so 192.168.1.0/24 covered nearly the whole IPv4 range instead of 256 addresses. Existing CIDR entries are now much narrower than they were.
  • Health check RestrictedIPs now 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-end range form from RestrictedIPs. Entries such as 192.168.1.0-192.168.1.255 now fail startup validation. Use CIDR instead.
  • RestrictedIPs entries 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.10 used to be read as octal and admit 8.10.10.10; 10.1 used to mean 10.0.0.1; 167772161 meant the same. All of these now fail startup validation instead of quietly admitting a host you did not name. 192.168.1.1/24 still means the whole 192.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-For or X-Real-IP value, 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.OpenApi and 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.x and v2.1.x documentation, which was previously missing.
  • The latest documentation now redirects to the current version, so existing links keep working.

🛠️ Migration Guide

To upgrade to v3.0.0, follow these steps:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. Update Packing Logs configuration

    • Move Path, FileName, DateFormat, and ChannelLimit out of the nested Packing block, directly under...
Read more

v2.1.1

Choose a tag to compare

@ChrisMavrommatis ChrisMavrommatis released this 12 Jan 22:57

Overview

  • Internal refactoring.
  • Removed Postman metadata from API documentation.
  • Updated packages.

⚙️ Core Changes

  • Removed external dependencies on ChrisMavrommatis.Features and ChrisMavrommatis.StartupTasks by implementing internal versions.
  • Consolidated logging (ChrisMavrommatis.Logging) and testing (ChrisMavrommatis.Shouldly) utilities into kernel modules and removed /dep folder.
  • Migrated solution file to new Visual Studio .slnx format.
  • Updated NuGet packages to latest stable versions.
  • Removed Postman-related metadata from API documentation files.