@gridlock/orchestrator 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/dist/AgentRoute.d.ts +44 -0
  3. package/dist/AgentRoute.d.ts.map +1 -0
  4. package/dist/AgentRoute.js +54 -0
  5. package/dist/AgentRoute.js.map +1 -0
  6. package/dist/CommandRegistry.d.ts +68 -0
  7. package/dist/CommandRegistry.d.ts.map +1 -0
  8. package/dist/CommandRegistry.js +87 -0
  9. package/dist/CommandRegistry.js.map +1 -0
  10. package/dist/ContextFactory.d.ts +62 -0
  11. package/dist/ContextFactory.d.ts.map +1 -0
  12. package/dist/ContextFactory.js +59 -0
  13. package/dist/ContextFactory.js.map +1 -0
  14. package/dist/DialogueGate.d.ts +117 -0
  15. package/dist/DialogueGate.d.ts.map +1 -0
  16. package/dist/DialogueGate.js +101 -0
  17. package/dist/DialogueGate.js.map +1 -0
  18. package/dist/DisclosureEngine.d.ts +160 -0
  19. package/dist/DisclosureEngine.d.ts.map +1 -0
  20. package/dist/DisclosureEngine.js +241 -0
  21. package/dist/DisclosureEngine.js.map +1 -0
  22. package/dist/EvidenceGraph.d.ts +71 -0
  23. package/dist/EvidenceGraph.d.ts.map +1 -0
  24. package/dist/EvidenceGraph.js +177 -0
  25. package/dist/EvidenceGraph.js.map +1 -0
  26. package/dist/InteractionEvaluator.d.ts +50 -0
  27. package/dist/InteractionEvaluator.d.ts.map +1 -0
  28. package/dist/InteractionEvaluator.js +205 -0
  29. package/dist/InteractionEvaluator.js.map +1 -0
  30. package/dist/KnowledgeBoundary.d.ts +74 -0
  31. package/dist/KnowledgeBoundary.d.ts.map +1 -0
  32. package/dist/KnowledgeBoundary.js +76 -0
  33. package/dist/KnowledgeBoundary.js.map +1 -0
  34. package/dist/evaluation/EscalationClock.d.ts +65 -0
  35. package/dist/evaluation/EscalationClock.d.ts.map +1 -0
  36. package/dist/evaluation/EscalationClock.js +106 -0
  37. package/dist/evaluation/EscalationClock.js.map +1 -0
  38. package/dist/evaluation/PerformanceEvaluator.d.ts +54 -0
  39. package/dist/evaluation/PerformanceEvaluator.d.ts.map +1 -0
  40. package/dist/evaluation/PerformanceEvaluator.js +161 -0
  41. package/dist/evaluation/PerformanceEvaluator.js.map +1 -0
  42. package/dist/evaluation/WorldState.d.ts +30 -0
  43. package/dist/evaluation/WorldState.d.ts.map +1 -0
  44. package/dist/evaluation/WorldState.js +43 -0
  45. package/dist/evaluation/WorldState.js.map +1 -0
  46. package/dist/evaluation/index.d.ts +8 -0
  47. package/dist/evaluation/index.d.ts.map +1 -0
  48. package/dist/evaluation/index.js +4 -0
  49. package/dist/evaluation/index.js.map +1 -0
  50. package/dist/evaluation/types.d.ts +26 -0
  51. package/dist/evaluation/types.d.ts.map +1 -0
  52. package/dist/evaluation/types.js +9 -0
  53. package/dist/evaluation/types.js.map +1 -0
  54. package/dist/handlers/AssistantCommandRegistry.d.ts +55 -0
  55. package/dist/handlers/AssistantCommandRegistry.d.ts.map +1 -0
  56. package/dist/handlers/AssistantCommandRegistry.js +59 -0
  57. package/dist/handlers/AssistantCommandRegistry.js.map +1 -0
  58. package/dist/handlers/EvidenceIngestion.d.ts +64 -0
  59. package/dist/handlers/EvidenceIngestion.d.ts.map +1 -0
  60. package/dist/handlers/EvidenceIngestion.js +114 -0
  61. package/dist/handlers/EvidenceIngestion.js.map +1 -0
  62. package/dist/handlers/GameLifecycle.d.ts +71 -0
  63. package/dist/handlers/GameLifecycle.d.ts.map +1 -0
  64. package/dist/handlers/GameLifecycle.js +100 -0
  65. package/dist/handlers/GameLifecycle.js.map +1 -0
  66. package/dist/handlers/GraphPopulation.d.ts +24 -0
  67. package/dist/handlers/GraphPopulation.d.ts.map +1 -0
  68. package/dist/handlers/GraphPopulation.js +21 -0
  69. package/dist/handlers/GraphPopulation.js.map +1 -0
  70. package/dist/handlers/ResolutionGate.d.ts +60 -0
  71. package/dist/handlers/ResolutionGate.d.ts.map +1 -0
  72. package/dist/handlers/ResolutionGate.js +49 -0
  73. package/dist/handlers/ResolutionGate.js.map +1 -0
  74. package/dist/index.d.ts +53 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +54 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/investigation/Analyst.d.ts +80 -0
  79. package/dist/investigation/Analyst.d.ts.map +1 -0
  80. package/dist/investigation/Analyst.js +514 -0
  81. package/dist/investigation/Analyst.js.map +1 -0
  82. package/dist/investigation/AnalystWorkspace.d.ts +182 -0
  83. package/dist/investigation/AnalystWorkspace.d.ts.map +1 -0
  84. package/dist/investigation/AnalystWorkspace.js +405 -0
  85. package/dist/investigation/AnalystWorkspace.js.map +1 -0
  86. package/dist/investigation/CaseFile.d.ts +92 -0
  87. package/dist/investigation/CaseFile.d.ts.map +1 -0
  88. package/dist/investigation/CaseFile.js +117 -0
  89. package/dist/investigation/CaseFile.js.map +1 -0
  90. package/dist/investigation/DiscoveryLayer.d.ts +133 -0
  91. package/dist/investigation/DiscoveryLayer.d.ts.map +1 -0
  92. package/dist/investigation/DiscoveryLayer.js +176 -0
  93. package/dist/investigation/DiscoveryLayer.js.map +1 -0
  94. package/dist/investigation/FactLedger.d.ts +91 -0
  95. package/dist/investigation/FactLedger.d.ts.map +1 -0
  96. package/dist/investigation/FactLedger.js +185 -0
  97. package/dist/investigation/FactLedger.js.map +1 -0
  98. package/dist/investigation/InvestigationTimeline.d.ts +98 -0
  99. package/dist/investigation/InvestigationTimeline.d.ts.map +1 -0
  100. package/dist/investigation/InvestigationTimeline.js +178 -0
  101. package/dist/investigation/InvestigationTimeline.js.map +1 -0
  102. package/dist/investigation/ProfileEngine.d.ts +84 -0
  103. package/dist/investigation/ProfileEngine.d.ts.map +1 -0
  104. package/dist/investigation/ProfileEngine.js +170 -0
  105. package/dist/investigation/ProfileEngine.js.map +1 -0
  106. package/dist/investigation/WorkspaceProjections.d.ts +94 -0
  107. package/dist/investigation/WorkspaceProjections.d.ts.map +1 -0
  108. package/dist/investigation/WorkspaceProjections.js +92 -0
  109. package/dist/investigation/WorkspaceProjections.js.map +1 -0
  110. package/dist/investigation/index.d.ts +18 -0
  111. package/dist/investigation/index.d.ts.map +1 -0
  112. package/dist/investigation/index.js +10 -0
  113. package/dist/investigation/index.js.map +1 -0
  114. package/dist/investigation/types.d.ts +206 -0
  115. package/dist/investigation/types.d.ts.map +1 -0
  116. package/dist/investigation/types.js +20 -0
  117. package/dist/investigation/types.js.map +1 -0
  118. package/dist/types.d.ts +283 -0
  119. package/dist/types.d.ts.map +1 -0
  120. package/dist/types.js +70 -0
  121. package/dist/types.js.map +1 -0
  122. package/package.json +48 -0
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Investigation Layer — Fact Ledger
3
+ *
4
+ * The Fact Ledger is the structured investigation memory for a single run.
5
+ * It stores FactRecords derived from evidence-layer outputs (artifacts,
6
+ * dialogue, validator findings) and organizes them for player-facing tools.
7
+ *
8
+ * Architectural boundary:
9
+ * - The Evidence Layer (Facts, Validators, Findings) produces truth.
10
+ * - The Fact Ledger records and organizes that truth.
11
+ * - The Fact Ledger never modifies validator outcomes or evidence-layer state.
12
+ */
13
+ export class FactLedger {
14
+ records = [];
15
+ /**
16
+ * Add a new FactRecord to the ledger.
17
+ * Duplicates are detected by (sourceType + sourceId + subject + statement).
18
+ * Returns true if the record was added, false if it was a duplicate.
19
+ */
20
+ add(record) {
21
+ if (this._isDuplicate(record)) {
22
+ return false;
23
+ }
24
+ this.records.push(record);
25
+ return true;
26
+ }
27
+ /**
28
+ * Retrieve a record by its unique id.
29
+ */
30
+ getById(id) {
31
+ return this.records.find(r => r.id === id);
32
+ }
33
+ /**
34
+ * Retrieve all records for a given subject.
35
+ */
36
+ getBySubject(subject) {
37
+ return this.records.filter(r => r.subject === subject);
38
+ }
39
+ /**
40
+ * Retrieve all records with a given status.
41
+ */
42
+ getByStatus(status) {
43
+ return this.records.filter(r => r.status === status);
44
+ }
45
+ /**
46
+ * Retrieve all records from a given source type.
47
+ */
48
+ getBySourceType(sourceType) {
49
+ return this.records.filter(r => r.sourceType === sourceType);
50
+ }
51
+ /**
52
+ * Update the status and optionally the confidence of a record.
53
+ */
54
+ updateStatus(id, status, confidence) {
55
+ const record = this.getById(id);
56
+ if (!record)
57
+ return;
58
+ record.status = status;
59
+ if (confidence !== undefined) {
60
+ record.confidence = confidence;
61
+ }
62
+ record.updatedAt = new Date().toISOString();
63
+ }
64
+ /**
65
+ * Retrieve a record by its original case-schema fact ID.
66
+ * Bridges FactLedger identity ↔ Evidence Graph node identity.
67
+ */
68
+ getByOriginFactId(originFactId) {
69
+ return this.records.find(r => r.originFactId === originFactId);
70
+ }
71
+ /**
72
+ * Add a related fact link to a record.
73
+ */
74
+ addRelatedFact(id, relatedFactId) {
75
+ const record = this.getById(id);
76
+ if (!record)
77
+ return;
78
+ if (!record.relatedFactIds.includes(relatedFactId)) {
79
+ record.relatedFactIds.push(relatedFactId);
80
+ record.updatedAt = new Date().toISOString();
81
+ }
82
+ }
83
+ /**
84
+ * Update the reliability (confidence) of a record without changing its status. (#229)
85
+ */
86
+ updateReliability(id, confidence) {
87
+ const record = this.getById(id);
88
+ if (!record)
89
+ return;
90
+ record.confidence = confidence;
91
+ record.updatedAt = new Date().toISOString();
92
+ }
93
+ // --- Query methods (#232) ---
94
+ /**
95
+ * Retrieve all records mentioning an entity (via relatedEntities, entityRefs, or legacy fields).
96
+ */
97
+ getByEntity(entityId) {
98
+ return this.records.filter(r => r.relatedEntities?.some(e => e.id === entityId) ||
99
+ r.entityRefs?.includes(entityId) ||
100
+ r.relatedCharacterIds.includes(entityId) ||
101
+ r.relatedArtifactIds.includes(entityId) ||
102
+ r.subject === entityId);
103
+ }
104
+ /**
105
+ * Retrieve all records from a given discovery method (sourceType alias).
106
+ */
107
+ getByMethod(method) {
108
+ return this.records.filter(r => r.sourceType === method);
109
+ }
110
+ /**
111
+ * Retrieve all records at a given reliability (confidence) level.
112
+ */
113
+ getByReliability(level) {
114
+ return this.records.filter(r => r.confidence === level);
115
+ }
116
+ /**
117
+ * Retrieve the full transitive chain of related facts starting from a given fact.
118
+ * Follows relatedFactIds links recursively, avoiding cycles.
119
+ */
120
+ getRelatedFacts(factId) {
121
+ const visited = new Set();
122
+ const result = [];
123
+ const walk = (id) => {
124
+ if (visited.has(id))
125
+ return;
126
+ visited.add(id);
127
+ const record = this.getById(id);
128
+ if (!record)
129
+ return;
130
+ if (id !== factId)
131
+ result.push(record);
132
+ for (const relId of record.relatedFactIds) {
133
+ walk(relId);
134
+ }
135
+ };
136
+ walk(factId);
137
+ return result;
138
+ }
139
+ /**
140
+ * Trace back to the root source of a fact via relatedFactIds.
141
+ * Returns the chain from the given fact to the earliest ancestor.
142
+ */
143
+ getProvenanceChain(factId) {
144
+ const chain = [];
145
+ const visited = new Set();
146
+ let currentId = factId;
147
+ while (currentId && !visited.has(currentId)) {
148
+ visited.add(currentId);
149
+ const record = this.getById(currentId);
150
+ if (!record)
151
+ break;
152
+ if (currentId !== factId)
153
+ chain.push(record);
154
+ const olderRelated = record.relatedFactIds.find(relId => {
155
+ const rel = this.getById(relId);
156
+ return rel && !visited.has(relId) && rel.discoveredAt <= record.discoveredAt;
157
+ });
158
+ currentId = olderRelated;
159
+ }
160
+ return chain;
161
+ }
162
+ /**
163
+ * Get all records in the ledger.
164
+ */
165
+ getAll() {
166
+ return [...this.records];
167
+ }
168
+ /**
169
+ * Get the total number of records.
170
+ */
171
+ get size() {
172
+ return this.records.length;
173
+ }
174
+ /**
175
+ * Duplicate detection using stable identity:
176
+ * sourceType + sourceId + subject + statement
177
+ */
178
+ _isDuplicate(record) {
179
+ return this.records.some(r => r.sourceType === record.sourceType &&
180
+ r.sourceId === record.sourceId &&
181
+ r.subject === record.subject &&
182
+ r.statement === record.statement);
183
+ }
184
+ }
185
+ //# sourceMappingURL=FactLedger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FactLedger.js","sourceRoot":"","sources":["../../src/investigation/FactLedger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Investigation Timeline (#247, #249, #250)
3
+ *
4
+ * Dual timeline: story time (in-world chronology) vs investigation time
5
+ * (player discovery order). Supports gap detection and overlap analysis.
6
+ *
7
+ * Engine-generic: operates on FactRecords from the DiscoveryLayer,
8
+ * not on product-specific scenario types. Time extraction uses
9
+ * regex patterns on fact statements and an optional structured-fact
10
+ * lookup callback for products that carry structured time data.
11
+ *
12
+ * No product vocabulary: no suspect, crime, case, accusation,
13
+ * investigation, contradiction.
14
+ *
15
+ * MS-28 #887 — Phase 1.2 — Orchestrator migration step 5.9.
16
+ */
17
+ import type { DiscoveryLayer } from './DiscoveryLayer.js';
18
+ export interface TimelineEntry {
19
+ factId: string;
20
+ subject: string;
21
+ statement: string;
22
+ /** In-world time (e.g., "14:00") — extracted from fact. Undefined if no time data. */
23
+ storyTime?: string;
24
+ /** ISO timestamp of when the player discovered this fact. */
25
+ discoveryTime: string;
26
+ sourceType: string;
27
+ sourceId: string;
28
+ }
29
+ /**
30
+ * A temporal gap — an unaccounted-for time window for an entity (#249).
31
+ */
32
+ export interface TemporalGap {
33
+ entityId: string;
34
+ gapStart: string;
35
+ gapEnd: string;
36
+ }
37
+ /**
38
+ * A temporal overlap — two entities with intersecting time windows (#250).
39
+ */
40
+ export interface TemporalOverlap {
41
+ entityA: string;
42
+ entityB: string;
43
+ overlapStart: string;
44
+ overlapEnd: string;
45
+ factIdA: string;
46
+ factIdB: string;
47
+ }
48
+ /**
49
+ * Optional callback for structured time extraction.
50
+ *
51
+ * Products that carry structured fact data (e.g. typed timestamp/time-window
52
+ * facts) can supply a lookup function that extracts start/end times from
53
+ * the original fact object. This is more reliable than regex on statements.
54
+ */
55
+ export interface StructuredTimeLookup {
56
+ /** Extract the start / primary time for a given fact ID. */
57
+ getStoryTime(factId: string): string | undefined;
58
+ /** Extract the end time for a given fact ID (for time-window facts). */
59
+ getEndTime(factId: string): string | undefined;
60
+ }
61
+ export declare class InvestigationTimeline {
62
+ private discoveryLayer;
63
+ private timeLookup?;
64
+ constructor(discoveryLayer: DiscoveryLayer, timeLookup?: StructuredTimeLookup | undefined);
65
+ /**
66
+ * Events ordered by in-world chronology (#247).
67
+ * Only facts with parseable time data are included.
68
+ */
69
+ getStoryTimeline(): TimelineEntry[];
70
+ /**
71
+ * Events ordered by player discovery time (#247).
72
+ */
73
+ getDiscoveryTimeline(): TimelineEntry[];
74
+ /**
75
+ * Entity-specific chronology (#247).
76
+ */
77
+ getTimelineForEntity(entityId: string): TimelineEntry[];
78
+ /**
79
+ * Events within a story time window (#247).
80
+ */
81
+ getTimelineRange(start: string, end: string): TimelineEntry[];
82
+ /**
83
+ * Identify temporal gaps for an entity (#249).
84
+ * Returns unaccounted-for time windows between known events.
85
+ */
86
+ getTemporalGaps(entityId: string): TemporalGap[];
87
+ /**
88
+ * Detect temporal overlaps between entities (#250).
89
+ * Finds pairs of entities with intersecting time windows.
90
+ */
91
+ getOverlaps(): TemporalOverlap[];
92
+ private _buildEntries;
93
+ private _extractStoryTime;
94
+ private _extractEndTime;
95
+ private _extractTimePoints;
96
+ private _timeDiffMinutes;
97
+ }
98
+ //# sourceMappingURL=InvestigationTimeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InvestigationTimeline.d.ts","sourceRoot":"","sources":["../../src/investigation/InvestigationTimeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAM1D,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,4DAA4D;IAC5D,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACjD,wEAAwE;IACxE,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAChD;AAMD,qBAAa,qBAAqB;IAE9B,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,UAAU,CAAC;gBADX,cAAc,EAAE,cAAc,EAC9B,UAAU,CAAC,EAAE,oBAAoB,YAAA;IAG3C;;;OAGG;IACH,gBAAgB,IAAI,aAAa,EAAE;IAMnC;;OAEG;IACH,oBAAoB,IAAI,aAAa,EAAE;IAKvC;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE;IAMvD;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE;IAO7D;;;OAGG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE;IA4BhD;;;OAGG;IACH,WAAW,IAAI,eAAe,EAAE;IA4ChC,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,gBAAgB;CAKzB"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Investigation Timeline (#247, #249, #250)
3
+ *
4
+ * Dual timeline: story time (in-world chronology) vs investigation time
5
+ * (player discovery order). Supports gap detection and overlap analysis.
6
+ *
7
+ * Engine-generic: operates on FactRecords from the DiscoveryLayer,
8
+ * not on product-specific scenario types. Time extraction uses
9
+ * regex patterns on fact statements and an optional structured-fact
10
+ * lookup callback for products that carry structured time data.
11
+ *
12
+ * No product vocabulary: no suspect, crime, case, accusation,
13
+ * investigation, contradiction.
14
+ *
15
+ * MS-28 #887 — Phase 1.2 — Orchestrator migration step 5.9.
16
+ */
17
+ // ---------------------------------------------------------------------------
18
+ // Service
19
+ // ---------------------------------------------------------------------------
20
+ export class InvestigationTimeline {
21
+ discoveryLayer;
22
+ timeLookup;
23
+ constructor(discoveryLayer, timeLookup) {
24
+ this.discoveryLayer = discoveryLayer;
25
+ this.timeLookup = timeLookup;
26
+ }
27
+ /**
28
+ * Events ordered by in-world chronology (#247).
29
+ * Only facts with parseable time data are included.
30
+ */
31
+ getStoryTimeline() {
32
+ return this._buildEntries()
33
+ .filter(e => e.storyTime !== undefined)
34
+ .sort((a, b) => a.storyTime.localeCompare(b.storyTime));
35
+ }
36
+ /**
37
+ * Events ordered by player discovery time (#247).
38
+ */
39
+ getDiscoveryTimeline() {
40
+ return this._buildEntries()
41
+ .sort((a, b) => a.discoveryTime.localeCompare(b.discoveryTime));
42
+ }
43
+ /**
44
+ * Entity-specific chronology (#247).
45
+ */
46
+ getTimelineForEntity(entityId) {
47
+ return this._buildEntries()
48
+ .filter(e => e.subject === entityId)
49
+ .sort((a, b) => (a.storyTime ?? '').localeCompare(b.storyTime ?? ''));
50
+ }
51
+ /**
52
+ * Events within a story time window (#247).
53
+ */
54
+ getTimelineRange(start, end) {
55
+ return this.getStoryTimeline().filter(e => {
56
+ if (!e.storyTime)
57
+ return false;
58
+ return e.storyTime >= start && e.storyTime <= end;
59
+ });
60
+ }
61
+ /**
62
+ * Identify temporal gaps for an entity (#249).
63
+ * Returns unaccounted-for time windows between known events.
64
+ */
65
+ getTemporalGaps(entityId) {
66
+ const entries = this.getTimelineForEntity(entityId)
67
+ .filter(e => e.storyTime !== undefined);
68
+ if (entries.length < 2)
69
+ return [];
70
+ const timePoints = this._extractTimePoints(entries);
71
+ if (timePoints.length < 2)
72
+ return [];
73
+ timePoints.sort((a, b) => a.localeCompare(b));
74
+ const gaps = [];
75
+ for (let i = 0; i < timePoints.length - 1; i++) {
76
+ const current = timePoints[i];
77
+ const next = timePoints[i + 1];
78
+ if (this._timeDiffMinutes(current, next) > 60) {
79
+ gaps.push({
80
+ entityId,
81
+ gapStart: current,
82
+ gapEnd: next,
83
+ });
84
+ }
85
+ }
86
+ return gaps;
87
+ }
88
+ /**
89
+ * Detect temporal overlaps between entities (#250).
90
+ * Finds pairs of entities with intersecting time windows.
91
+ */
92
+ getOverlaps() {
93
+ const facts = this.discoveryLayer.getDiscoveredFacts();
94
+ const overlaps = [];
95
+ const windows = [];
96
+ for (const fact of facts) {
97
+ const storyTime = this._extractStoryTime(fact);
98
+ if (!storyTime)
99
+ continue;
100
+ const endTime = this._extractEndTime(fact);
101
+ if (endTime) {
102
+ windows.push({ entityId: fact.subject, start: storyTime, end: endTime, factId: fact.id });
103
+ }
104
+ }
105
+ for (let i = 0; i < windows.length; i++) {
106
+ for (let j = i + 1; j < windows.length; j++) {
107
+ const a = windows[i];
108
+ const b = windows[j];
109
+ if (a.entityId === b.entityId)
110
+ continue;
111
+ const overlapStart = a.start > b.start ? a.start : b.start;
112
+ const overlapEnd = a.end < b.end ? a.end : b.end;
113
+ if (overlapStart < overlapEnd) {
114
+ overlaps.push({
115
+ entityA: a.entityId,
116
+ entityB: b.entityId,
117
+ overlapStart,
118
+ overlapEnd,
119
+ factIdA: a.factId,
120
+ factIdB: b.factId,
121
+ });
122
+ }
123
+ }
124
+ }
125
+ return overlaps;
126
+ }
127
+ // --- Private helpers ---
128
+ _buildEntries() {
129
+ return this.discoveryLayer.getDiscoveredFacts().map(r => ({
130
+ factId: r.id,
131
+ subject: r.subject,
132
+ statement: r.statement,
133
+ storyTime: this._extractStoryTime(r),
134
+ discoveryTime: r.discoveredAt,
135
+ sourceType: r.sourceType,
136
+ sourceId: r.sourceId,
137
+ }));
138
+ }
139
+ _extractStoryTime(record) {
140
+ // Prefer structured fact data via lookup
141
+ if (this.timeLookup && record.originFactId) {
142
+ const time = this.timeLookup.getStoryTime(record.originFactId);
143
+ if (time)
144
+ return time;
145
+ }
146
+ // Fallback to regex for records without structured data
147
+ const match = record.statement.match(/(\d{1,2}:\d{2})/);
148
+ return match ? match[1] : undefined;
149
+ }
150
+ _extractEndTime(record) {
151
+ // Prefer structured fact data via lookup
152
+ if (this.timeLookup && record.originFactId) {
153
+ const time = this.timeLookup.getEndTime(record.originFactId);
154
+ if (time)
155
+ return time;
156
+ }
157
+ // Fallback to regex
158
+ const match = record.statement.match(/to\s+(\d{1,2}:\d{2})/);
159
+ return match ? match[1] : undefined;
160
+ }
161
+ _extractTimePoints(entries) {
162
+ const points = [];
163
+ for (const e of entries) {
164
+ if (e.storyTime)
165
+ points.push(e.storyTime);
166
+ const endMatch = e.statement.match(/to\s+(\d{1,2}:\d{2})/);
167
+ if (endMatch)
168
+ points.push(endMatch[1]);
169
+ }
170
+ return [...new Set(points)];
171
+ }
172
+ _timeDiffMinutes(a, b) {
173
+ const [aH, aM] = a.split(':').map(Number);
174
+ const [bH, bM] = b.split(':').map(Number);
175
+ return (bH * 60 + bM) - (aH * 60 + aM);
176
+ }
177
+ }
178
+ //# sourceMappingURL=InvestigationTimeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InvestigationTimeline.js","sourceRoot":"","sources":["../../src/investigation/InvestigationTimeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Profile Engine (#242, #243, #245, #246)
3
+ *
4
+ * Computes dynamic entity profiles from discovered evidence.
5
+ * Profiles are NEVER stored — always computed from DiscoveryLayer.
6
+ *
7
+ * Engine-generic: operates on FactRecords and Findings, not on
8
+ * product-specific scenario types. No product vocabulary.
9
+ *
10
+ * MS-28 #887 — Phase 1.2 — Orchestrator migration step 5.9.
11
+ */
12
+ import type { FactRecord } from './types.js';
13
+ import type { DiscoveryLayer } from './DiscoveryLayer.js';
14
+ import type { Finding } from '@gridlock/validators';
15
+ export interface ProfileRelationship {
16
+ targetEntity: string;
17
+ relationshipType: string;
18
+ evidenceBasis: string[];
19
+ strength: 'weak' | 'moderate' | 'strong';
20
+ }
21
+ export type ProfileDepth = 'shallow' | 'developing' | 'detailed' | 'comprehensive';
22
+ export interface EntityProfile {
23
+ entityId: string;
24
+ entityType: string;
25
+ knownFacts: FactRecord[];
26
+ contradictions: Finding[];
27
+ findings: Finding[];
28
+ aggregateReliability: 'low' | 'medium' | 'high';
29
+ discoveryDepth: ProfileDepth;
30
+ relationships: ProfileRelationship[];
31
+ }
32
+ /**
33
+ * Delta between two profile snapshots (#243).
34
+ */
35
+ export interface ProfileDelta {
36
+ entityId: string;
37
+ newFacts: FactRecord[];
38
+ newContradictions: Finding[];
39
+ depthChange: {
40
+ from: ProfileDepth;
41
+ to: ProfileDepth;
42
+ } | null;
43
+ }
44
+ /**
45
+ * Comparison between two entity profiles (#246).
46
+ */
47
+ export interface ProfileComparison {
48
+ entityA: string;
49
+ entityB: string;
50
+ sharedFacts: FactRecord[];
51
+ interEntityContradictions: Finding[];
52
+ overlappingRelationships: string[];
53
+ }
54
+ export declare class ProfileEngine {
55
+ private discoveryLayer;
56
+ private findings;
57
+ private lastSeenProfiles;
58
+ constructor(discoveryLayer: DiscoveryLayer, findings: Finding[], lastSeen?: Map<string, EntityProfile>);
59
+ /**
60
+ * Get the last-seen profiles map (for state preservation across recreations).
61
+ */
62
+ getLastSeenProfiles(): Map<string, EntityProfile>;
63
+ /**
64
+ * Build a dynamic profile for an entity (#242).
65
+ */
66
+ buildProfile(entityId: string): EntityProfile;
67
+ /**
68
+ * Compute delta vs last-seen profile (#243).
69
+ */
70
+ computeDelta(entityId: string): ProfileDelta;
71
+ /**
72
+ * Mark the current profile as "seen" by the player (#243).
73
+ */
74
+ markSeen(entityId: string): void;
75
+ /**
76
+ * Compare two entity profiles (#246).
77
+ */
78
+ compareProfiles(entityA: string, entityB: string): ProfileComparison;
79
+ private _inferEntityType;
80
+ private _computeAggregateReliability;
81
+ private _computeDepth;
82
+ private _buildRelationships;
83
+ }
84
+ //# sourceMappingURL=ProfileEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProfileEngine.d.ts","sourceRoot":"","sources":["../../src/investigation/ProfileEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAOpD,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;CAC1C;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,eAAe,CAAC;AAEnF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,cAAc,EAAE,OAAO,EAAE,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,oBAAoB,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAChD,cAAc,EAAE,YAAY,CAAC;IAC7B,aAAa,EAAE,mBAAmB,EAAE,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,iBAAiB,EAAE,OAAO,EAAE,CAAC;IAC7B,WAAW,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,EAAE,EAAE,YAAY,CAAA;KAAE,GAAG,IAAI,CAAC;CAC9D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,yBAAyB,EAAE,OAAO,EAAE,CAAC;IACrC,wBAAwB,EAAE,MAAM,EAAE,CAAC;CACpC;AAMD,qBAAa,aAAa;IAItB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,QAAQ;IAJlB,OAAO,CAAC,gBAAgB,CAA6B;gBAG3C,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,OAAO,EAAE,EAC3B,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC;IAKvC;;OAEG;IACH,mBAAmB,IAAI,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC;IAIjD;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IA0B7C;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IA0B5C;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB;IA6BpE,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,4BAA4B;IAQpC,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,mBAAmB;CA+B5B"}