fix(confidence-engine): project unexplained transitions

This commit is contained in:
2026-09-05 13:15:11 +01:00
parent e1839147b1
commit 55e935066c
3 changed files with 69 additions and 0 deletions
+6
View File
@@ -33,6 +33,12 @@
- The read-back rule requires relationship type, endpoint direction, and description to agree. Provenance and interpretation-separation rules remain unchanged.
- Deterministic tests prove the instruction exists, not that the model obeys it. No live call has tested this refinement; next restart point is live directional-integrity validation before broader repeatability testing.
## Unexplained-transition projection coverage
- Starting checkpoint: `e183914`. The latest one-call v0.5 validation emitted two reconstruction relationships: one directionally clean relationship projected, while the other (`r1`) was semantically/directionally incoherent and lost because it referenced an `unexplainedTransition` without graph projection.
- `unexplainedTransitions` now project as unresolved transition nodes and register their source IDs for existing relationship projection; the relationship architecture itself was not redesigned.
- The semantic coherence of live `r1` remains a separate unresolved reasoning issue; intervention-fit E was absent in that run and remains unresolved. No live validation has occurred after this deterministic fix.
## Current product architecture
Three distinct routes, not a single page:
+18
View File
@@ -204,6 +204,24 @@ export function buildInitialGraph(analysisData) {
}
}
// Unexplained transitions remain unresolved transition nodes
if (reconstruction.unexplainedTransitions) {
for (const trans of reconstruction.unexplainedTransitions) {
const label =
trans.description ||
`${trans.entity ?? "Unexplained transition"}: ${trans.previousState ?? "unknown"}${trans.currentState ?? "unknown"}`;
mapSourceId(trans.id, ensureNode(
label,
"transition",
"unknown",
trans.description || label,
null,
null,
trans.confidence || "low",
));
}
}
// Known transitions
if (reconstruction.knownTransitions) {
for (const trans of reconstruction.knownTransitions) {
+45
View File
@@ -269,6 +269,51 @@ describe("buildInitialGraph", () => {
}));
});
it("projects relationships referencing unexplained transition source IDs", () => {
const reconstruction = {
...makeReconstructionFixture(),
observedStates: [
{ id: "obs-rate", description: "Complaint rate is not yet known", confidence: "high" },
],
unexplainedTransitions: [
{
id: "ut-1",
description: "Support wait time increased without an explanation",
entity: "Support",
previousState: "2 hours",
currentState: "8 hours",
confidence: "medium",
},
],
relationships: [{
id: "r-transition",
fromId: "obs-rate",
toId: "ut-1",
relationship: "depends_on",
description: "Understanding the rate depends on the unexplained transition.",
confidence: "medium",
}],
};
const result = buildInitialGraph({ reconstruction, evidence: [] });
const rateNode = result.nodes.find((node) => node.label === "Complaint rate is not yet known");
const transitionNode = result.nodes.find(
(node) => node.description === "Support wait time increased without an explanation",
);
expect(transitionNode).toMatchObject({
kind: "transition",
status: "unknown",
description: "Support wait time increased without an explanation",
});
expect(result.edges).toContainEqual(expect.objectContaining({
id: "e-rel-r-transition",
fromNodeId: rateNode.id,
toNodeId: transitionNode.id,
relationship: "depends_on",
}));
});
it("skips relationships with invalid source IDs without creating substitute nodes", () => {
const reconstruction = {
...makeReconstructionFixture(),