Phases 0 to 2 made structured facts provable. The remaining truth about a project lives in prose: ticket comments, meeting notes, risk write-ups. Phase 3 makes that text retrievable through the graph rather than beside it, so an answer about a risk can only draw on chunks that are actually linked to that project's entities.
Three risks dominate the programme:
Only one layer really changes. Retrieval graduates from a fixed template library to genuine hybrid search, and the LLM picks up its third bounded job: extraction from prose, confidence gated and human confirmed.
Console gains the retrieval trace view and community summaries. React
runningThird job added: propose triples from prose, confidence gated, human confirmed. bge-m3 embeddings
extendedUnchanged. Rules can now fire on facts extracted from notes. React Flow
runningUnchanged, still the only source of numbers. SPARQL · OR-Tools
runningChunking, entity linking, pgvector search, RRF fusion, Leiden community summaries. pgvector · igraph
newNow also stores chunk-to-entity links and community memberships. Oxigraph
runningSame database now holds the vector index, so there is no extra service. PostgreSQL + pgvector
runningComment and description text starts flowing as first-class events. Jira
runningStructured data tells you a ticket is late. It rarely tells you why. The reason usually sits in a comment, a retro note or a risk write-up, in someone's own words. Phase 3 makes that written material searchable, but only through the project structure, so an answer about your programme cannot quietly quote a document about a different one.
This is the phase that lets the system answer "why", and open questions no one wrote a report for.
The upper band runs when text arrives. The lower band runs when a question is asked. The important structural decision is that a chunk is only retrievable through entities it is linked to, which is what stops the classic RAG failure of confidently quoting the wrong project.
Ordinary AI search finds text that sounds similar to your question. That is exactly how these systems end up confidently quoting the wrong project, because a note about a different programme can sound extremely relevant.
We run two searches and keep only what both agree on: text that reads relevant, and records the project map confirms are actually connected to what you asked. A note with no verified connection to your project is never used in an answer, however well it matches.
The hard rule: a chunk with no link into the graph is not retrievable. It can sit in the index forever, but it will never reach an answer, because scope is decided by the graph and not by cosine distance.
Splits prose into windows that keep their author, timestamp, and source event, so a chunk inherits both clocks like every other fact.
deterministic · no modelMaps mentions to ontology IRIs using the identity map plus exact and fuzzy matching, with the LLM only proposing uncertain links for confirmation.
the step that earns the "Graph" in GraphRAGbge-m3 or nomic-embed served through the same OpenAI-compatible endpoint, written into pgvector inside the existing database.
pgvector · one less serviceVector candidates fused with the graph neighbourhood by reciprocal rank fusion, the approach that outperformed both alone in published enterprise evaluations.
k = 60Leiden clustering over the task and dependency graph produces workstream-level summaries, which is what makes whole-programme questions answerable at all.
igraph · refreshed on changeEvery query records what was retrieved, what was fused, and what was dropped. A client can audit why a chunk did or did not influence an answer.
stored as eventsOf these six components, one policy matters more than the rest: a piece of text with no verified link into the project map is not retrievable. It can sit in the index indefinitely and will never reach an answer.
The workstream summaries are the other notable item. By grouping related work automatically, the system can answer questions about the programme as a whole, not just questions about individual tickets someone already knew to ask about.
Extraction stays deliberately timid. Where a note implies a fact worth acting on, the system proposes it and waits for a human, because a small local model reading meeting notes is the least reliable component in the building.
Each chunk keeps its author, timestamp, and originating event.
The chunk is attached to the entities it actually talks about.
Stored in pgvector next to the events, never leaving the appliance.
RRF ranks what both signals agree on, and drops the rest.
Chunk IDs are citations like any fact ID, clickable to the original text.
Written material is split into passages that keep their author and date, linked to the projects and people they genuinely mention, and indexed locally. When a question arrives, the two searches run and are merged, and the surviving passages are cited in the answer exactly like any other record.
Click a citation and you land in the original comment, with the person who wrote it and when. The system quotes your organisation's own words back to you, with attribution, rather than paraphrasing them into something unverifiable.
The acceptance test plants a convincing but irrelevant note from another project, then demonstrates the system retrieving it by text similarity and visibly discarding it because the project map says it does not belong. That is the guardrail proving itself in public.
Any AI vendor can show you a good answer. This shows you the bad answer being caught.