This tracks the separate in-flight input-version gap noted in the review of #775. I reproduced it against dev (87df718) on Linux with PostgreSQL 16.15 and a scripted HTTP model; no real model or timing sleeps are involved.
A definition edited while type alignment is waiting for the model can be treated as already considered, even though neither vote saw the new definition.
Reproduction:
- Start with one class whose description is
OLD definition and one entity with kind word company.
- Run the real
align_types worker. After the mock endpoint receives the first request, it commits a class edit (description = 'NEW definition', updated_at = clock_timestamp()) before returning the response.
- Return
none for both votes. Both captured requests contain OLD definition, not the updated description.
- The binding's
decided_at is later than the class edit, type_bindings::stale returns nothing, and a second worker run sends no new model requests.
The desired boundary is that a result based on an older definition should either be discarded/requeued or remain detectably stale. Merely widening the negative-cache predicate, as #775 does, cannot catch an edit hidden behind the later response timestamp.
A standalone reproduction branch adds only a test module to the dev baseline. With an isolated migrated pgvector/PostgreSQL database (the fixture also runs migrations):
UTOPIA_DATABASE_URL=postgres://... \
UTOPIA_TEST_REQUIRE_DB=1 \
cargo test -p utopia-server version_repro -- --nocapture
It passed in the isolated Linux build. Passing means the assertions reproduced the current incorrect freshness result, not that the gap is fixed; this test-only branch is not a proposed mergeable fix.
I have limited the dynamic claim to type alignment. This is a design follow-up for choosing the input-revision contract, per CONTRIBUTING, rather than a request to expand #792 or change the schema without agreement. Human decisions should retain their existing precedence.
This tracks the separate in-flight input-version gap noted in the review of #775. I reproduced it against
dev(87df718) on Linux with PostgreSQL 16.15 and a scripted HTTP model; no real model or timing sleeps are involved.A definition edited while type alignment is waiting for the model can be treated as already considered, even though neither vote saw the new definition.
Reproduction:
OLD definitionand one entity with kind wordcompany.align_typesworker. After the mock endpoint receives the first request, it commits a class edit (description = 'NEW definition', updated_at = clock_timestamp()) before returning the response.nonefor both votes. Both captured requests containOLD definition, not the updated description.decided_atis later than the class edit,type_bindings::stalereturns nothing, and a second worker run sends no new model requests.The desired boundary is that a result based on an older definition should either be discarded/requeued or remain detectably stale. Merely widening the negative-cache predicate, as #775 does, cannot catch an edit hidden behind the later response timestamp.
A standalone reproduction branch adds only a test module to the dev baseline. With an isolated migrated pgvector/PostgreSQL database (the fixture also runs migrations):
UTOPIA_DATABASE_URL=postgres://... \ UTOPIA_TEST_REQUIRE_DB=1 \ cargo test -p utopia-server version_repro -- --nocaptureIt passed in the isolated Linux build. Passing means the assertions reproduced the current incorrect freshness result, not that the gap is fixed; this test-only branch is not a proposed mergeable fix.
I have limited the dynamic claim to type alignment. This is a design follow-up for choosing the input-revision contract, per CONTRIBUTING, rather than a request to expand #792 or change the schema without agreement. Human decisions should retain their existing precedence.