feat: implement #98 semantic project knowledge normalization #458
No reviewers
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
nsaspy/prolog-rlm!458
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "rage/98-semantic-project-knowledge"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
#98 — Normalize captures into semantic project facts
Runtime invariant implemented
The #97 grouped capture layer now has a semantic normalization layer:
rlm_project_semanticturns the current extraction's grouped matches intoclosed definitions/references/calls/imports/exports observations with exact
provenance (project, file hash/generation, content hash, parse identity and
generation, grammar ref, pack identity/sha/purpose, adapter identity, syntax
node, byte/point spans). Extraction and resolution stay separate operations
with explicit resolved/unresolved/ambiguous/external states; duplicate names
stay distinct
project_symbol/4identities and surface asambiguous.Derived containment, bounded cycle-safe call reachability, and file
dependency relations are computed on demand and expose their supporting
observation ids. The public surface emits the #288-compatible
symbol_index{project, kinds, definitions, coherence}over still-currentknowledge only, consumable by
plan_graph_resolve_symbol/3directly.Freshness reuses #97 currentness: stale extractions cannot answer current
queries, pack replacement invalidates dependent semantic state, and
currentness is never journaled — the #97 extraction journal stays
authoritative, so fresh-process restarts cannot resurrect superseded
semantic facts as current (proven by kill/restart fixtures, including the
stale path).
Zero-matches and unsupported-capability states remain distinct via
language_analysis_capability/2. Common Lisp proves the adapter surface isnot Python/JS-shaped (keyword-disambiguated kinds, S-expression calls, and
imports/exports declared
unsupported). No model calls, no scheduler, noconsult/1, no new authority; #377/#380 are deliberately untouched.Non-goals
project_knowledge_expert(#377/#380).Tests / evidence
test/rlm_project_semantic_test.plcovering all#98 acceptance points plus two fresh-process restart fixtures, registered
through the native tree-sitter gate: 84/84 green (nix).
a regression test in
rlm_tree_sitter_query_test.deterministic corpus, native suite, benchmark deterministic 16/16, CLI
demo smoke, git diff --check.
Follow-up scope
#99 minimum coherent snapshot/freshness work -> #377 expert registry ->
#380 project knowledge expert -> #381 retrieval expert.
Review-fix push (
fa41aa3) — 6 operator-review findings addressed, root-caused from the 21-failure regression:Runtime fixes
semantic_publication/3row per extraction publication; publish/snapshot self-attach the target journal (multi-project processes never cross-write). The silentgoal_failedcascade was a bare persistency query used as an assert — plain failure, no exception, invisible through the async facade.hydrate_rows/2consumes the publication-pair row shape; observation ids restart at 1 per publication, so re-normalization re-journals an identical row and hydration replay is idempotent (fixes duplicateproject_symbolfacts across re-publication/restart).project_semantic_adapter_register/3— capabilities alone no longer overstate the surface.knowledge_state/resolve/symbol_index/file_dependencies/definitions) best-effort hydrates;registry_clearkeeps the shared journal attachment while other registries use it.resolvereturnsok(incomplete(unresolved|ambiguous, missing(Files)))when registered project files lack current semantic knowledge; symbol_index coherence ispartial(stale(Files), unindexed(Files)), complete only when both are empty.Test corrections (runtime was right, tests were wrong): registry_clear now expects
currentafter clear (public reads self-hydrate, matching the phase2 self-hydration proof); subset-dict pattern replaced withIndex2.coherence == complete; ambiguous-resolve fixture now carries two same-name definitions so ambiguity is genuine (2 symbols) with missing files reported.Evidence: native tree-sitter suite 88/88; full prolog-verify gate pass (check_runtime, load_all, run_tests 1235, benchmark deterministic, CLI demo, git diff --check). rlm_async untouched.
Merged on green: all six forgejo gates success at
dfc96cb(deterministic CI x2, pack-install, tree-sitter FFI, paid OpenRouter lane, Nix flake after the runner install fix indfc96cb— the installer action hung on systemd-less docker runners; the four flake checks themselves are unchanged and were passing locally throughout). Merge commit51d2530f0e.