Repository navigation
0.13.3 - 2026-08-22
Release Notes
A patch release closing the upgrade-path regression 0.13.2 introduced, scoping the last two
ontology-driven maintenance operations to a single group, and adding per-group ontologies. The group
boundary work that began in 0.13.0 is now consistent across reads, writes, deletes and maintenance:
an operation names the group it acts on, and touches nothing else.
Fixed
-
migrate_wal_root_if_needednow stamps a generation for the legacy flat WAL it migrates. A
legacy flat WAL (.lcg/wal/*.jsonl, pre-0.13.0) predates generation identity (#387) entirely,
and migration now assumes it is locally owned (an assumption, not a proof — see #431's
Assumptions section), minting one for the destination group as part of the same relocation —
the same actWalWriter::newperforms for any other stream
created with no prior content. This closes the gap without weakening #414's refusal for any
other reason a stream might arrive with no generation (e.g. a publish step that dropped the
dot-namespace): the new call is scoped strictly to the exact directory this migration just
relocated content into, never a general sweep over every group.knowledge_statusnow reports
a non-nullgenerationandgeneration_status: "known"for a freshly migrated group. See
ADR-0414's amendment note. (#431) -
knowledge_rebuild_from_wal's unknown-generation refusal message now names both possible
remedies. The two situations that produce this refusal — a received stream whose sidecar was
stripped, and a workspace migrated by a binary older than this fix — are indistinguishable on
disk, so the message can no longer assume which one applies. It now states both: republish the
stream's full directory if it came from a publisher, or hand-create.wal-generation.jsonfor a
local workspace with no publisher. (#431) -
knowledge_canonicalize_relationsandknowledge_backfill_relation_typesnow require a
group_idand are fully group-scoped. Both previously selectedRelatesToNode_candidates
database-wide with no group filter and flushed every mutation to the default group's WAL
stream, regardless of which group's data they actually touched. On a multi-group workspace, the
correct, intended use of either operation — canonicalizing the one group a node owns — rewrote
every co-resident group's edges as a side effect and misattributed the resulting mutations to
the default group's stream. This is the same failure class as #368/#406 (cross-group mutation)
and #385 (WAL misattribution), previously left as a documented exception for these two
operations.group_idis now required from the outset — omitted,null, or empty is rejected
rather than falling back to a database-wide rewrite or the default group. No known deployment
invoked either operation before this fix, so the required parameter breaks no existing caller.
See ADR-0378's FR-004 section and ADR-0385's Context section, both amended by this issue. (#447) -
The legacy
.graphiti→.lcgworkspace migration now honoursLCG_WAL_DIR/
GRAPHITI_WAL_DIR. It always moved.graphiti/walto a hardcoded.lcg/wal, so a workspace
configured with a custom WAL root had its legacy content land somewhere the service would never
read — the WAL was intact on disk and invisible to the process. The move now targets the resolved
WAL root, handles a destination on a different filesystem (a custom root often is), and merges into
a root that already has content rather than failing. (#442)
Changed
- BREAKING:
group_idis now a required, non-empty parameter on
knowledge_canonicalize_relationsandknowledge_backfill_relation_types, on both the MCP and
IPC surfaces. The MCP tool schemas for both methods movegroup_idfrom optional into
required. A caller that previously omittedgroup_id(absent,null, or empty) got a
successful — and, per the### Fixedentry above, cross-group — rewrite; it now receives an
error naming the missing parameter instead, and no rows are read or written. The remedy is to
pass the caller's own group explicitly; there is no default to fall back to, because a silent
default (the default group) is the defect this release fixes. Unlike #406's equivalent change,
no known deployment invokes either operation today, so this breaks no existing caller in
practice — see the issue's Release timing discussion. (#447)
Added
- Per-group ontology support. A
group_idcan now have its own extraction/validation
vocabulary, independent of every other co-resident group in the same workspace. Place a
group-specific ontology at{workspace}/.lcg/ontology/<group_id>.yaml(using the existing
ontology YAML format); agroup_idunsafe as a bare filesystem path component is
percent-encoded with the same bijective scheme already used for per-group WAL directory names.
A group with no per-group file falls back to the existing workspace-wide.lcg/ontology.yaml,
exactly as before this feature — a workspace that hasn't adopted per-group ontologies behaves
identically to pre-0.14.0. The resolved per-group ontology governs, for that group only,
extraction guidance,mode: strictvalidation, canonicalization, and reprocessing
(knowledge_reprocess_entity_types,knowledge_reprocess_relation_types). A malformed or
unreadable per-group file falls back to the workspace-wide ontology when one exists, or to no
ontology otherwise (logged either way), rather than failing the group's extraction outright.
Direct-assert
(knowledge_assert_entity/knowledge_assert_relationship) is unaffected, as before. When a
group's stream is published, the ontology that guided its extraction now travels alongside it
as.wal-ontology.json— a new, purely informational addition to the publish contract (see
Operations): a consumer can inspect it as documentation, but it is never
applied to the consumer's own extraction, validation, canonicalization, or reprocessing, and its
absence never affects replay or correctness. See Ontology
for the full resolution/fallback contract. (#446) knowledge_statusreports a newhydration_statusfield, alongside the existing
applied_seq/max_seqvalues, in both the flatwalobject and everywal_groups[*]entry:
"hydrated"(the database is caught up with its WAL),"wal_ahead"(the WAL holds content the
database has not applied — e.g. a wiped or fresh database beside a populated WAL directory), or
"not_applicable"(the group has no WAL content at all). Previously, a genuinely empty group and
a group whose WAL was simply ahead of the DB were indistinguishable unless a caller manually
comparedapplied_seqagainstmax_seqitself. Purely additive —applied_seq/max_seqare
unchanged, andhealth_check'shealthy/degradeddetermination is unaffected. (#456)
Internal
- The required CI test gate could not fail. The
testjob pipedcargo testthroughtee
withoutpipefail, so the pipeline reportedtee's status and a failing suite still went green.
(#430) - Four tests that had been failing behind that masked gate were fixed once it started reporting
honestly — stale fixtures and drifted assertions, not new breakage. (#429) - Startup migration ordering is documented and regression-tested. The
.graphiti→.lcgmove
must precede the per-group WAL relocation, or a.graphiti-era workspace leaves its WAL files
loose and invisible. The ordering was already correct via the call graph — it was diagnosed as
broken from textual line order — so this hardens an implicit dependency with explicit
preconditions and un-quarantines the regression test #430 had parked. (#437) - Socket-connectability is documented as not a readiness signal. The socket binds before the
database opens, deliberately, so recovery IPC stays reachable in degraded mode (ADR-0009); the
correct signal is ahealth_checkround-trip reportinghealthy, which cannot be true until
after migration. (#436) wal_root_migration's legacy-upgrade acceptance test now runs in CI. It drives the real
74MB/12,481-seq fixture through migration and asserts parity with 0.13.1's rebuild, and had run
only when invoked by hand — while five defects accumulated on the path it guards. (#460)- The real-corpus fixture's
group_idnow matches the WAL directory it migrates into. It was
captured under a non-default group while committed in the flat pre-0.13.0 layout, so its content
and directory disagreed — a shape no deployment has, which was nonetheless read as a product
defect. (#469)
lcg-eval 0.13.3
Install lcg-eval 0.13.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/verveguy/liminis-context-graph/releases/download/v0.13.3/lcg-eval-installer.sh | shDownload lcg-eval 0.13.3
| File | Platform | Checksum |
|---|---|---|
| lcg-eval-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| lcg-eval-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| lcg-eval-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
lcg-service 0.13.3
Install lcg-service 0.13.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/verveguy/liminis-context-graph/releases/download/v0.13.3/lcg-service-installer.sh | shDownload lcg-service 0.13.3
| File | Platform | Checksum |
|---|---|---|
| lcg-service-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| lcg-service-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| lcg-service-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |