Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,32 @@ may change in any release. See the status note in the README.

## [Unreleased]

## [0.5.7] — 2026-10-31

A maintenance release: dependency updates since 0.5.6, one security fix in the frontend, and a test flake fixed.
Nothing in the configuration, the API or the schema changes, and there is no new migration. The database image moves
to `pgvector/pgvector:0.8.7-pg18`, a patch release of the extension on the same Postgres major, so the data
directory and its mount stay as they are.

### Changed

- **Spring Boot 4.1.2, Gradle 9.8.2, bun 1.4.4, Testcontainers 2.0.5, Spotless 8.10.4, Vitest 5 with Angular 22.2**,
and the rest of the backend and frontend minor and patch updates. The frontend image builds on Node.js 24, and its
runtime is `nginx-unprivileged` 1.31.
- **The database image is `pgvector/pgvector:0.8.7-pg18`**, in Compose and for the tests alike; Renovate had moved
only the Compose file, so for a while the tests checked a different image than the one that ships.
- **`@angular-architects/ngrx-toolkit` is replaced by `@ngrx-toolkit/core`**, the package's new name from v22 on.
- **Spring AI stays at 2.0.1.** 2.0.2 brings an openai-java (from 4.66.0) whose stream close releases the transport
under an in-flight read, so stopping a turn or hitting its deadline no longer ends the model call. Renovate proposes
Spring AI in a pull request of its own from now on.

### Fixed

- **dompurify 3.4.17**, which closes three advisories on 3.4.16 and earlier (critical: `SAFE_FOR_TEMPLATES` bypass in
shadow roots; high: an `IN_PLACE` hook left event handlers armed; low: the SMIL `href` guard skipped for XHTML).
- **The suggestion prewarm tests no longer fail on a loaded runner.** The model stub counted a connection dropped
before its body as a request and handed it the next scripted reply.

## [0.5.6] — 2026-10-13

The chat's model picker shows what each model costs and what the chat has spent, every turn records its tokens and
Expand Down Expand Up @@ -1778,7 +1804,8 @@ Found while building the demo, all of them in paths only a container exercises:
left six.
- The shortlist card printed the description's Markdown syntax in its teaser.

[Unreleased]: https://github.com/codeministry/leadgen/compare/v0.5.6...HEAD
[Unreleased]: https://github.com/codeministry/leadgen/compare/v0.5.7...HEAD
[0.5.7]: https://github.com/codeministry/leadgen/releases/tag/v0.5.7
[0.5.6]: https://github.com/codeministry/leadgen/releases/tag/v0.5.6
[0.5.5]: https://github.com/codeministry/leadgen/releases/tag/v0.5.5
[0.5.4]: https://github.com/codeministry/leadgen/releases/tag/v0.5.4
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Violating one of these is expensive, and most of them fail silently.
bulk-archive: these run against the live instance from the terminal or as direct SQL. A
one-off admin task that leaves a commit behind has been done wrong, because the next
release then carries a migration nobody asked for.
- **The database image is the pinned `pgvector/pgvector:0.8.6-pg18`, set in `docker-compose.yml` and `Databases.java` and nowhere else.** — reasoning in `docs/decisions/retrieval.md`.
- **The database image is the pinned `pgvector/pgvector:0.8.7-pg18`, set in `docker-compose.yml` and `Databases.java` and nowhere else.** — reasoning in `docs/decisions/retrieval.md`.
- **Mount the database volume at `/var/lib/postgresql`, never `…/data`; a major bump moves tag, `PGDATA`, mount and data at once.** — reasoning in `docs/decisions/retrieval.md`.
- **The vector column is 2000 wide, a wider vector is truncated at the seam, and thresholds move only after measuring with `docs/samples/measure_embeddings.ts`.** — reasoning in `docs/decisions/retrieval.md`.
- **No CV tailoring.** Fixed PDFs in `config/documents/`, selected by the language
Expand Down
2 changes: 1 addition & 1 deletion backend/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ plugins {
}

group = "de.codeministry"
version = "0.5.6"
version = "0.5.7"

/*
* Java 25 through the toolchain rather than the ambient JDK: Gradle runs on
Expand Down
2 changes: 1 addition & 1 deletion backend/smoke/docker-compose.smoke.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The smoke stack, as an OVERLAY on `docker-compose.yml` and never as a file of its own.
#
# `postgres` is inherited verbatim, which is the point: `pgvector/pgvector:0.8.6-pg18` is
# `postgres` is inherited verbatim, which is the point: `pgvector/pgvector:0.8.7-pg18` is
# named in exactly two places in this repository and a third copy is a third thing to
# forget on the next major. Run it as
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public record ConfigProperties(

// One home per default, read by the bound constructor and the hand-built one alike, so
// the two cannot drift. `@DefaultValue` takes a compile-time constant, hence strings.
private static final String DEFAULT_VERSION = "0.5.6";
private static final String DEFAULT_VERSION = "0.5.7";
private static final String DEFAULT_CONFIG_POLL_INTERVAL = "PT2S";
private static final String DEFAULT_SCORE_BATCH_POLL_INTERVAL = "PT5M";
private static final String DEFAULT_INGEST_CRON = "-";
Expand Down
6 changes: 3 additions & 3 deletions backend/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ spring:
name: leadgen
# What a client reads in the `initialize` result: the running build, from the one place
# the build names itself (leadgen.version below).
version: ${LEADGEN_VERSION:0.5.6}
version: ${LEADGEN_VERSION:0.5.7}
# STREAMABLE and not SSE: Spring AI 2.0 deprecates SSE, and Streamable HTTP is what
# current MCP clients negotiate.
protocol: STREAMABLE
Expand All @@ -43,10 +43,10 @@ spring:
# not have to exist — without it the defaults apply.
leadgen:
# What the header shows, and the only place the running build names itself. Without this
# line the default on ConfigProperties applies and every image reports 0.5.6 —
# line the default on ConfigProperties applies and every image reports 0.5.7 —
# the Gradle version is not injected into the jar, and the Dockerfile copies libs/*.jar
# by glob, so nothing else carries it either. The deploy sets it from the image tag.
version: ${LEADGEN_VERSION:0.5.6}
version: ${LEADGEN_VERSION:0.5.7}
config-dir: ${LEADGEN_CONFIG_DIR:config}
security:
# Asserts that something outside this process decides who reaches the port, which is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public final class Databases {
* no target here that could miss it. The trap is written out beside the mount it applies
* to.
*/
public static final String IMAGE = "pgvector/pgvector:0.8.6-pg18";
public static final String IMAGE = "pgvector/pgvector:0.8.7-pg18";

private Databases() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ void flywayCreatedTheBaselineSchema() {

@Test
void theVectorExtensionIsThereAndTheColumnHasAWidth() {
// The image is the thing under test here. `pgvector/pgvector:0.8.6-pg18` is a plain
// The image is the thing under test here. `pgvector/pgvector:0.8.7-pg18` is a plain
// postgres with the extension added, and on any image without it `V22` fails at startup
// naming the extension rather than the image — which is a long way from the compose file
// that actually decides it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
// into the `spring-boot-webmvc-test` module. The old import compiles against
// Boot 3 and simply does not exist here.
@WebMvcTest(StatusController.class)
@TestPropertySource(properties = {"spring.application.name=lead-generation", "leadgen.version=0.5.6"})
@TestPropertySource(properties = {"spring.application.name=lead-generation", "leadgen.version=0.5.7"})
class StatusControllerTest {

@Autowired
Expand All @@ -30,6 +30,6 @@ void returnsApplicationNameAndVersion() {
Assertions.assertThat(mvc.get().uri("/api/v1/status"))
.hasStatusOk()
.bodyJson()
.isEqualTo("{\"application\":\"lead-generation\",\"version\":\"0.5.6\"}");
.isEqualTo("{\"application\":\"lead-generation\",\"version\":\"0.5.7\"}");
}
}
2 changes: 1 addition & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ flowchart LR
direction TB
web["web<br/>nginx serving the Angular build,<br/>/api proxied to api:8080"]
api["api<br/>Spring Boot: the pipeline,<br/>the REST API, the schedulers"]
db[("postgres<br/>pgvector/pgvector:0.8.6-pg18")]
db[("postgres<br/>pgvector/pgvector:0.8.7-pg18")]
web --> api --> db
end
subgraph outside["outside the machine"]
Expand Down
2 changes: 1 addition & 1 deletion docs/decisions/native-image.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ healthy service.
It is a bash script and a compose **overlay**, not a Gradle task and not a compose file of
its own. Not a Gradle task because it runs a container on a runner and dragging the
configuration cache and the toolchain into that buys nothing. An overlay because
`pgvector/pgvector:0.8.6-pg18` is named in exactly two places in this repository and a
`pgvector/pgvector:0.8.7-pg18` is named in exactly two places in this repository and a
third copy is a third thing to forget on the next major — `postgres` is inherited verbatim
and only GreenMail, WireMock and the service under test are added. That service is called
`smoke-api` and not `api`, because `api` carries a `build:` block an overlay cannot remove
Expand Down
2 changes: 1 addition & 1 deletion docs/decisions/retrieval.md
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ test there was, and it was available at any point.

## Moved from the root CLAUDE.md

- **The database image is `pgvector/pgvector:0.8.6-pg18`, not plain postgres.** Deduplication's
- **The database image is `pgvector/pgvector:0.8.7-pg18`, not plain postgres.** Deduplication's
two similarity strategies compare vectors, `V22` creates the extension, and an image without
it fails that migration with an error naming the extension rather than the image. It is named
in `docker-compose.yml` and once for the tests in
Expand Down
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "frontend",
"version": "0.5.6",
"version": "0.5.7",
"scripts": {
"start": "ng serve",
"build": "ng build",
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('App', () => {
const fixture = TestBed.createComponent(App);
fixture.detectChanges();

httpMock.expectOne('/api/v1/status').flush({application: 'lead-generation', version: '0.5.6'});
httpMock.expectOne('/api/v1/status').flush({application: 'lead-generation', version: '0.5.7'});
// Run ingest and the model choice left the header for the workflow screen (operator,
// 2026-09-27), so the shell does not create the scoring-model store: the model list is
// not asked for here. The ingest store is created at the root (fix 2F-5), so its
Expand All @@ -34,7 +34,7 @@ describe('App', () => {
await fixture.whenStable();
fixture.detectChanges();

expect(fixture.nativeElement.textContent).toContain('lead-generation 0.5.6');
expect(fixture.nativeElement.textContent).toContain('lead-generation 0.5.7');
httpMock.verify();
});

Expand Down
Loading