Passive diagnostic. Coherent and scattered inputs produce identical
edge topology — every unknown connects to the summary node (kind=state)
via depends_on regardless of semantics. Shared edges are wiring, not
coherence evidence.
Creates tests/graph/shared-anchor-production-path.test.js (36 tests, all pass).
Experiment 49 asks whether any sequence of real production updates via
applyValidatedProposal creates two or more active unknowns sharing the same
populated relationship anchor. Two sequential-update scenarios (Cases A & B)
consistently returned separate_anchors or insufficient_data — no shared
anchor observed in tested flows.
Control cases C–F confirm: diagnostic correctly distinguishes shared vs
separated patterns on controlled fixtures; all produced nodes/edges pass
schema validation; resolving one node does not mutate another (immunity);
decomposition children share parent anchor correctly.
Combined regression suite: 78 tests across Exp 47 (26), Exp 48 (16),
Exp 49 (36) — all passing, no production code modified.
Experiment 48 passively audited whether real graph updates populate usable
unknown relationships. Three production paths inspected:
- buildInitialGraph: does NOT populate dependsOn/affects/parentId (only edges)
- buildEmergentReasoningUnknown: DOES populate dependsOn and parentId
- buildCompositeUnknownChildren: DOES populate parentId
One test file created (16 tests, all pass). Diagnostic confirms shared-anchor
coherence is structurally supportable through Path 2 only, requiring at least
two active unknowns with shared references. Conclusion: Insufficient Data for
the initial-build path; production code correctly populates fields in emergent
path but requires comparable observations to trigger.
Experiment 47: created a test-only diagnostic helper that inspects existing
graph relationship fields (dependsOn, affects, parentId, childIds on nodes;
fromNodeId/toNodeId + relationship on edges) to distinguish coherent
investigations (multiple unknowns sharing one anchor) from scattered ones.
Three controlled fixtures confirm the helper works: shared_anchor vs
separate_anchors vs insufficient_data — all with identical structural counts
(6 nodes, 4 active unknowns). All three produce identical too_broad output
from the existing assessor, confirming no production code changes needed.
Existing-scenario inspection (3 real scenarios from Exp 39-46) all return
insufficient_data — current data lacks populated relationship fields on
unknown nodes. This means the gap is not purely in assessment logic but also
in upstream data quality.
Closed Experiment 46. Updated design-evolution-log and handoff.
Experiment 45 — passive boundary experiment measuring the existing
assessor's too_broad threshold from two to five competing unknowns.
Key findings:
- Boundary switches exactly between three and four active unknowns
- Clarify eligibility follows the same boundary
- Resolved-item gate works correctly (1 stays too_broad, 2 clears it)
- 2–3 unknowns return cannot_determine health (not healthy or too_broad)
- Boundary appears mechanically clear but conceptually uncertain
No production code changed. Synthetic fixtures only.
Passive diagnostic: zero Clarify-eligible turns across 10 real-scenario
assessments. Two findings — (1) orienting-based rule is dead code because
assessor never produces phase=orienting, (2) too_broad trigger validly narrow
but untested by any fixture. Created focused test file with 31 assertions.
All regression tests pass: 51 behaviour-selection + 33 reachability + 51
assessor = 166 total.
Experiment 41 compared two passive alternatives for reducing Acknowledge dominance:
Variant A (priority reordering): evaluate Summarise/Pause before Acknowledge
- Converges on concluding→summarise and stalled→pause correctly
- Introduces false-positive summarise at long-investigation t3
Variant B (Acknowledge exclusions): gate Acknowledge via phase/progress/health
- Converges on the same two genuine changes without false-positives
- Recommended: cleaner boundaries, preserves Acknowledge for healthy focus states
Both variants produce identical results for 2 of 7 tested turns.
Variant A diverges at long-investigation t3 (focusing phase with resolvedNodeCount=3).
Variant B correctly preserves Acknowledge there via its exclusion list.
Test files:
- tests/behaviour-selection.counterfactual.test.js (44 tests, new)
No production code changed.
Experiment 30 classified two deferred documents against verified current state:
- architectural-principles.md → keep as task-specific reference (6 current, 4 aspirational, 3 duplicates)
- backlog info.md → retain temporarily pending revision (mixed mock fixtures + deferred UX planning)
Neither moved to archive — both contain material with potential near-term utility.
Created docs/document-role-review.md with evidence, routing test, and return-to-work note.
Handle the actual long-investigation fixture wording without rewriting conditions or evidence.
Fixes:
- Add 'is achievable' to future-feasibility phrase list so present-state evidence correctly leaves future conditions unresolved (different_timeframe scope)
- Add 'european equivalent' to differentiation related keywords so observation-5 evidence directly shares the differentiation concept with the condition (direct_match scope)
Updates:
- decision-condition-status tests to use present-state condition text where needed, and correct expectations for the two actual fixture cases
- Evidence-condition-scope tests for both actual fixture examples
- Design evolution log with Experiment 25B findings confirming long-investigation statuses
Move EVIDENCE_DIRECTION_GROUPS out of the mock fixture library into
lib/graph/evidence-direction.js where it belongs. Remove unused
DECISION_CONDITIONS and CONTRADICTION_KEYWORDS exports from scenarios.
Add Experiment 24A entry to the design log.
Implement Experiment 19: deterministic behaviour selector with five
behaviours (Acknowledge, Clarify, Summarise, Continue, Pause).
- lib/behaviour-selection/behaviour-selector.js — Pure function selector
applying v0.1 rules in priority order (acknowledge > clarify > summarise >
pause > continue). Defaults to Continue with low confidence when no rule
matches or assessment is incomplete. Guards against partial objects.
- tests/behaviour-selector.test.js — 51 tests covering all five behaviours,
priority ordering, contract conformance, determinism, edge cases, and
scenario-based validation with mock investigations.
- docs/design-evolution-log.md — Close Experiment 18 (record what assessor
enabled for Behaviour Selection), add Experiment 19 section with hypothesis,
scope, evaluation criteria, and open questions.
Passive integration only: no changes to reasoning engine, prompts, graph
generation, decomposition, narrative generation, API contracts, UI behaviour,
or Ollama integration.
Implement the three-dimensional assessment (phase, progress, conversation
health) that sits between narrative and behaviour selection.
Key changes:
- lib/assessment/investigation-state-assessor.js: assessor module with
countObservations, assessPhase, assessProgress, assessConversationHealth,
assessInvestigationState — deterministic classifiers using known rules
- tests/investigation-state-assessor.test.js: 51 tests covering phase
classification (orienting→concluding), progress thresholds, health
conditions, confidence aggregation, edge cases, and observation counting
- lib/graph/orchestrator.js: integration calls passing correctly-shaped input
to assessInvestigationState() at three call sites (~552, ~904, ~1013)
Design decisions encoded in this iteration:
- countObservations counts nodes with known/resolved status + high-confidence
non-unknown non-state nodes (not just explicit observation-kind nodes)
- Phase uses seven values including cannot_determine for insufficient data
- Progress uses resolution ratio thresholds: accelerating (>0.6), steady
(0.2-0.6), stalled (<0.2 with ≥1 resolved)
- Overall confidence = minimum across all three dimensions (conservative)
Also adds investigation-state-assessment-contract.md and updates
design-evolution-log, investigation-state-assessment.md (status header),
and investigation-turn-cycle.md (implementation status table).
Compress the speculative 452-line architecture spec into a constraint-focused
experiment brief. Reduce the initial behaviour set to five patterns
(Acknowledge, Clarify, Summarise, Continue, Pause) — the smallest useful
subset for testing whether behaviour selection improves over 'always ask'.
Remove: arbitrary weights/scores, convergence requirements, phase-constrained
tables (design preferences not discoveries), rationale output infrastructure,
Behaviour Readiness dimension specs.
Keep: five behaviours with plain condition-matching rules, explicit v0.1 scope
boundary, Future Considerations section for deferred architecture items.
Also add Behaviour Selection entry to reasoning-contract-backlog and mark
Stage 4 (State Assessment) as implemented in investigation-turn-cycle.
Close Experiment 15 (Facilitator Behaviour Specification).
Introduce Experiment 16 — Investigation State Assessment.
- Create docs/investigation-state-assessment.md with 7 assessment dimensions:
Current Investigation Phase, Investigation Progress, Evidence Quality,
Understanding Trajectory, Uncertainty Trend, Conversation Health,
and Behaviour Readiness. Each dimension includes purpose, observable
signals, possible values, and how behaviours may consume it.
- Document 6 assessment principles (Assess Not Decide, All Signals
Traceable to Narrative, Descriptive Not Prescriptive, Convergence Over
Single Signal, Stateful Across Turns, Uncertainty About Assessment Is
Itself Assessable).
- Include exploratory decision matrix linking investigation states to
likely behaviours with reasons.
- Prepend Behaviour Selection section to docs/facilitator-behaviour.md
recording that behaviours are selected from Investigation State
Assessment and do not inspect graph nodes directly.
- Update docs/design-evolution-log.md: close Experiment 15, add
Experiment 16 closure, record emerging architecture with the new layer
between Narrative and Behaviour Selection.
No implementation. Documentation only. No changes to reasoning engine,
graph generation, prompts, orchestrator, APIs, Ollama integration, or UI.
- Create docs/facilitator-behaviour.md: behavioural specification of the
Confidence Engine with 14 identified behaviours (Orient, Acknowledge,
Observe pattern, Clarify, Validate, Connect, Challenge assumption, Refine
understanding, Expose uncertainty, Decide direction, Know when to pause,
Avoid premature closure, Communicate confidence honestly, Progressively
narrow focus).
- Update docs/design-evolution-log.md: add Experiment 15 entry documenting
what Experiment 14 proved, what emerged (the gap is behavioural not visual),
and why the next phase focuses on conversation behaviour over UI.
- Update .claude/ux-guidelines.md: add Facilitator Behaviour section with
core behavioural principles, anti-patterns, state-aware selection criteria,
and architecture relationship.
No code changes — this is a behavioural specification for future implementation.
Emphasise the active investigation card through stronger elevation,
clearer borders, and improved spacing. Quiet supporting panels by
reducing border opacity, softening heading weight, and lowering
text contrast — making them available without competing for attention.
Facilitator card receives a warm surface tint to read as a briefing
card rather than a generic panel.
Documentation: close experiment 05 with findings, add experiment 06
to the design evolution log, add Attention Hierarchy to UX guidelines,
defer dark mode to a future Investigation Mode experiment.
Presentation changes only — no reasoning, prompts, graph, API, or
backend modifications.
Phase 2: Recovery state components (ProviderUnavailableCard,
MalformedResponseCard, UnexpectedStateCard, ContinueLaterBanner) with
automatic error detection for provider/network/malformed/unexpected states.
Phase 3: Session persistence via sessionStorage — save after each
successful turn, restore on mount, clear on restart/reset. Continuelater banner shown when session is restored.
Phase 4: InvestigationSummaryPanel component displaying current status,
understanding summary, questions answered/remaining, investigation timestamps.
Phase 5: docs/reasoning-contract-backlog.md documenting all mocked
fields (60+ rows across 7 categories) with feature/UI need/mock/desired
output/stage/notes columns.
Also: wired onRestart through ReasoningWorkspace → ScenarioForm, fixed
getErrorType scope issues, removed broken window.__restartInvestigation.
The response form now appears immediately after the active question
so the user can read and answer without scrolling. Everything else
becomes supporting context beneath the interaction area.