9.7 KiB
Investigation State Assessment Contract
Status: Passive / Experimental Implementation Implemented in code during Experiments 18–25B but does not control active user-facing investigation routing. This document defines the data contract that was tested; the capability remains passive.
Architecture Experiment 18 — First Executable Slice
This document defines the data contract for the investigation state assessment layer. It is the interface between investigation narrative (Stage 3) and behaviour selection (Stage 5).
Implementation status
- Implemented in code: Yes — first executable slice deployed (Experiment 18).
- Active routing authority: No — passive experimental capability isolated from user-facing investigation.
Versioning
{
"version": "v0.1", // Schema version — increment only on field additions/removals
"assessedAt": "ISO-8601", // When this assessment was computed
"confidence": "high|medium|low" // Overall assessment confidence
}
All fields below are part of the v0.1 contract. Adding new fields requires a version bump to v0.2+. Removing or renaming existing fields also requires a version bump.
Assessment Object Shape
Phase
Evaluates where the investigation is in its lifecycle.
{
"phase": {
"value": "orienting|exploring|focusing|deepening|synthesising|concluding|cannot_determine",
"confidence": "high|medium|low",
"signals": [string], // Descriptive reasons for the classification
"evidence": { // What data supported this classification
"resolvedNodeCount": number,
"activeUnknownCount": number,
"unknownResolutionRatio": number | null,
"observationDensity": number | null,
"evidenceDepth": string | null // "shallow|moderate|deep"
}
}
}
Progress
Tracks whether understanding is advancing, stalled, or regressing.
{
"progress": {
"value": "accelerating|steady|stalled|looping|spiralling|cannot_determine",
"confidence": "high|medium|low",
"signals": [string],
"evidence": {
"turnCount": number,
"recentResolutionsLastTurn": number,
"newUnknownsPerTurn": number | null,
"repeatedNodeIds": string[] // Nodes appearing across 3+ turns without resolution
}
}
}
Conversation Health
Evaluates whether the conversation pattern is productive.
{
"conversationHealth": {
"value": "healthy|repetitive|too_broad|too_narrow|user_overloaded|user_under_informed|cannot_determine",
"confidence": "high|medium|low",
"signals": [string],
"evidence": {
"questionTypeDistribution": Record<string, number> | null, // reasoningPattern -> count
"activeUnknownCount": number,
"resolvedNodeRatio": number | null,
"hasActiveQuestion": boolean | null,
"summaryLength": number | null
}
}
}
Overall Assessment
All dimensions combined:
{
"version": "v0.1",
"assessedAt": "ISO-8601",
"confidence": "high|medium|low",
"phase": { ... },
"progress": { ... },
"conversationHealth": { ... }
}
Deterministic Rules (Phase)
The phase classifier uses conservative thresholds and defaults to cannot_determine when data is insufficient.
Values
| Phase | Classification Rule |
|---|---|
concluding |
activeUnknownCount === 0 AND resolvedNodeCount >= 2 AND hasActiveQuestion === false — investigation has reached terminal state |
synthesising |
activeUnknownCount <= 1 AND resolvedNodeRatio > 0.5 — near completion, synthesis possible |
focusing |
activeUnknownCount === 1 AND knownObservations >= 3 — single remaining unknown with sufficient context |
exploring |
observationCount >= 2 AND unknownResolutionRatio < 0.4 — gathering initial evidence |
orienting |
observationCount < 2 OR totalNodeCount < 3 — insufficient structure to classify |
deepening |
Residual: activeUnknownCount > 1 AND resolvedNodeCount >= 3 — structured investigation with remaining unknowns |
cannot_determine |
Insufficient data for any of the above classifications |
Thresholds (Conservative)
- A node is "known" only if
kind === "observation"OR (kind !== "unknown"ANDstatus !== "provisional"). - An unknown is "active" only if
kind === "unknown"AND status is not"resolved". - Resolution ratio = resolvedNodeCount / totalNonEmptyNodeCount (null if total is 0).
- Known observation density threshold: ≥3 observations before classifying as
focusingor above.
Deterministic Rules (Progress)
Progress uses a single-snapshot approximation for this first slice. Multi-turn history tracking is reserved for a future version.
Values
| Progress | Classification Rule |
|---|---|
accelerating |
unknownResolutionRatio > 0.6 — resolving unknowns faster than they accumulate |
steady |
unknownResolutionRatio > 0.2 AND unknownResolutionRatio <= 0.6 — balanced progress |
stalled |
unknownResolutionRatio < 0.2 AND resolvedNodeCount >= 1 — some work done but no momentum |
looping |
repeatedNodeIds.length > 0 (nodes appearing across turns) AND resolvedNodeCount === 0 for those nodes |
spiralling |
newUnknownsPerTurn > resolvedNodeCount for recent history (requires turn history) |
cannot_determine |
resolvedNodeCount === 0 AND totalNodeCount <= 2 — no sufficient data yet |
Thresholds (Conservative)
- Resolution ratio = resolvedNodeCount / totalNonEmptyNodeCount.
- No progress classification is assigned below 1 resolved node.
- If resolution ratio cannot be computed (total === 0 or all nodes unresolved), return
cannot_determine.
Deterministic Rules (Conversation Health)
Conversation health evaluates the interaction pattern from available graph signals.
Values
| Health | Classification Rule |
|---|---|
healthy |
Has active unknown AND has active question AND resolution ratio between 0 and 0.9 |
repetitive |
Same reasoning pattern appears in >50% of questions (requires historical data) |
too_broad |
Multiple active unknowns (>3) without sufficient resolved context (<2 resolved) |
too_narrow |
Single observation with single unknown and no edges connecting them |
user_overloaded |
Active unknown count > 4 (exceeds working memory limit) |
user_under_informed |
Total observations < 2 AND active question exists (asking without enough context) |
cannot_determine |
Insufficient graph signals to evaluate conversation pattern |
Thresholds (Conservative)
- "Has active unknown" =
activeUnknownCount > 0. - "Has active question" =
selectedQuestion !== null. - Resolution ratio for healthy = between 0 and 0.9 (not terminal, not empty).
Confidence Rules
Overall Confidence
The overall confidence is the minimum of all dimension confidences. If any dimension cannot be determined, overall confidence is "low".
Per-Dimension Confidence
| Confidence | Condition |
|---|---|
high |
Classification supported by ≥2 independent signals AND data is complete (no null evidence fields) |
medium |
Classification supported by 1 signal AND data is mostly complete (≤1 null evidence field) |
low |
Classification supported by partial data OR has null evidence fields >1 |
What This Contract Must Never Do
- Never invent signals. Only use data actually present in the graph schema, orchestrator diagnostics, or facilitator-view outputs.
- Never reach false precision. When data is ambiguous, return
cannot_determinerather than a confident but unsupported classification. - Never mutate input state. This is a pure function — no side effects, no writes, no network calls.
- Never bypass the narrative layer. Assessment reads from narrative output and graph data, never directly from raw user input.
- Never prescribe behaviour. Assessment describes state only; interpretation belongs to behaviour selection.
Supported Data Sources (v0.1)
| Source | Fields Available |
|---|---|
situationGraph.nodes[] |
id, label, description, kind, status, confidence, evidenceIds, dependsOn, affects |
situationGraph.resolvedNodeIds[] |
Array of resolved node IDs |
situationGraph.activeUnknownNodeId |
Nullable string — currently targeted unknown |
selectedQuestion |
{ nodeId, question, reason } nullable |
diagnostics.reasoningPattern |
Current turn's reasoning pattern key |
diagnostics.nodeCount |
Total node count |
diagnostics.edgeCount |
Total edge count |
facilitatorView._meta |
isTerminal, hasUnresolvedUnknowns, totalObservations, unresolvedUnknownsCount |
Unsupported Signals (Planned for Future Versions)
These signals are specified in the investigation-state-assessment architecture document but require data not yet available in v0.1:
- Evidence Quality — requires per-node evidence confidence scoring across multiple sources
- Understanding Trajectory — requires comparing narrative complexity across turns
- Uncertainty Trend — requires tracking which unknowns are resolved and by what pattern
- Behaviour Readiness — requires mapping assessment output to behaviour inventory
These are tracked in reasoning-contract-backlog.md.
Recording Note
This contract was drafted for Experiment 18's first executable slice. It captures the minimal viable assessment object shape derived from actual repository data contracts (schema.js, orchestrator.js, facilitator-view-adapter.js). The capability is implemented in code but remains passive/experimental — it does not control active user-facing investigation routing. Future experiments may add dimensions and signals as the graph schema and diagnostics evolve.