gitmem-mcp 0.2.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.
- package/CHANGELOG.md +47 -0
- package/CLAUDE.md.template +65 -0
- package/LICENSE +21 -0
- package/README.md +221 -0
- package/bin/gitmem.js +383 -0
- package/dist/commands/check.d.ts +33 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +492 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/constants/closing-questions.d.ts +40 -0
- package/dist/constants/closing-questions.d.ts.map +1 -0
- package/dist/constants/closing-questions.js +107 -0
- package/dist/constants/closing-questions.js.map +1 -0
- package/dist/diagnostics/anonymizer.d.ts +55 -0
- package/dist/diagnostics/anonymizer.d.ts.map +1 -0
- package/dist/diagnostics/anonymizer.js +191 -0
- package/dist/diagnostics/anonymizer.js.map +1 -0
- package/dist/diagnostics/channels.d.ts +132 -0
- package/dist/diagnostics/channels.d.ts.map +1 -0
- package/dist/diagnostics/channels.js +150 -0
- package/dist/diagnostics/channels.js.map +1 -0
- package/dist/diagnostics/collector.d.ts +183 -0
- package/dist/diagnostics/collector.d.ts.map +1 -0
- package/dist/diagnostics/collector.js +227 -0
- package/dist/diagnostics/collector.js.map +1 -0
- package/dist/diagnostics/index.d.ts +28 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +31 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/absorb-observations.d.ts +63 -0
- package/dist/schemas/absorb-observations.d.ts.map +1 -0
- package/dist/schemas/absorb-observations.js +25 -0
- package/dist/schemas/absorb-observations.js.map +1 -0
- package/dist/schemas/active-sessions.d.ts +71 -0
- package/dist/schemas/active-sessions.d.ts.map +1 -0
- package/dist/schemas/active-sessions.js +19 -0
- package/dist/schemas/active-sessions.js.map +1 -0
- package/dist/schemas/analyze.d.ts +38 -0
- package/dist/schemas/analyze.d.ts.map +1 -0
- package/dist/schemas/analyze.js +30 -0
- package/dist/schemas/analyze.js.map +1 -0
- package/dist/schemas/common.d.ts +55 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +65 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/create-decision.d.ts +48 -0
- package/dist/schemas/create-decision.d.ts.map +1 -0
- package/dist/schemas/create-decision.js +31 -0
- package/dist/schemas/create-decision.js.map +1 -0
- package/dist/schemas/create-learning.d.ts +107 -0
- package/dist/schemas/create-learning.d.ts.map +1 -0
- package/dist/schemas/create-learning.js +64 -0
- package/dist/schemas/create-learning.js.map +1 -0
- package/dist/schemas/get-transcript.d.ts +24 -0
- package/dist/schemas/get-transcript.d.ts.map +1 -0
- package/dist/schemas/get-transcript.js +22 -0
- package/dist/schemas/get-transcript.js.map +1 -0
- package/dist/schemas/index.d.ts +23 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +23 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/log.d.ts +36 -0
- package/dist/schemas/log.d.ts.map +1 -0
- package/dist/schemas/log.js +27 -0
- package/dist/schemas/log.js.map +1 -0
- package/dist/schemas/prepare-context.d.ts +41 -0
- package/dist/schemas/prepare-context.d.ts.map +1 -0
- package/dist/schemas/prepare-context.js +31 -0
- package/dist/schemas/prepare-context.js.map +1 -0
- package/dist/schemas/recall.d.ts +41 -0
- package/dist/schemas/recall.d.ts.map +1 -0
- package/dist/schemas/recall.js +47 -0
- package/dist/schemas/recall.js.map +1 -0
- package/dist/schemas/record-scar-usage-batch.d.ts +82 -0
- package/dist/schemas/record-scar-usage-batch.d.ts.map +1 -0
- package/dist/schemas/record-scar-usage-batch.js +25 -0
- package/dist/schemas/record-scar-usage-batch.js.map +1 -0
- package/dist/schemas/record-scar-usage.d.ts +51 -0
- package/dist/schemas/record-scar-usage.d.ts.map +1 -0
- package/dist/schemas/record-scar-usage.js +32 -0
- package/dist/schemas/record-scar-usage.js.map +1 -0
- package/dist/schemas/save-transcript.d.ts +38 -0
- package/dist/schemas/save-transcript.d.ts.map +1 -0
- package/dist/schemas/save-transcript.js +30 -0
- package/dist/schemas/save-transcript.js.map +1 -0
- package/dist/schemas/search.d.ts +36 -0
- package/dist/schemas/search.d.ts.map +1 -0
- package/dist/schemas/search.js +27 -0
- package/dist/schemas/search.js.map +1 -0
- package/dist/schemas/session-close.d.ts +371 -0
- package/dist/schemas/session-close.d.ts.map +1 -0
- package/dist/schemas/session-close.js +95 -0
- package/dist/schemas/session-close.js.map +1 -0
- package/dist/schemas/session-start.d.ts +46 -0
- package/dist/schemas/session-start.d.ts.map +1 -0
- package/dist/schemas/session-start.js +33 -0
- package/dist/schemas/session-start.js.map +1 -0
- package/dist/schemas/thread.d.ts +72 -0
- package/dist/schemas/thread.d.ts.map +1 -0
- package/dist/schemas/thread.js +39 -0
- package/dist/schemas/thread.js.map +1 -0
- package/dist/server.d.ts +22 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +313 -0
- package/dist/server.js.map +1 -0
- package/dist/services/active-sessions.d.ts +66 -0
- package/dist/services/active-sessions.d.ts.map +1 -0
- package/dist/services/active-sessions.js +311 -0
- package/dist/services/active-sessions.js.map +1 -0
- package/dist/services/agent-detection.d.ts +25 -0
- package/dist/services/agent-detection.d.ts.map +1 -0
- package/dist/services/agent-detection.js +93 -0
- package/dist/services/agent-detection.js.map +1 -0
- package/dist/services/analytics.d.ts +201 -0
- package/dist/services/analytics.d.ts.map +1 -0
- package/dist/services/analytics.js +483 -0
- package/dist/services/analytics.js.map +1 -0
- package/dist/services/cache.d.ts +148 -0
- package/dist/services/cache.d.ts.map +1 -0
- package/dist/services/cache.js +384 -0
- package/dist/services/cache.js.map +1 -0
- package/dist/services/cache.test.d.ts +8 -0
- package/dist/services/cache.test.d.ts.map +1 -0
- package/dist/services/cache.test.js +267 -0
- package/dist/services/cache.test.js.map +1 -0
- package/dist/services/compliance-validator.d.ts +30 -0
- package/dist/services/compliance-validator.d.ts.map +1 -0
- package/dist/services/compliance-validator.js +257 -0
- package/dist/services/compliance-validator.js.map +1 -0
- package/dist/services/config.d.ts +48 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/config.js +128 -0
- package/dist/services/config.js.map +1 -0
- package/dist/services/embedding.d.ts +58 -0
- package/dist/services/embedding.d.ts.map +1 -0
- package/dist/services/embedding.js +243 -0
- package/dist/services/embedding.js.map +1 -0
- package/dist/services/gitmem-dir.d.ts +38 -0
- package/dist/services/gitmem-dir.d.ts.map +1 -0
- package/dist/services/gitmem-dir.js +84 -0
- package/dist/services/gitmem-dir.js.map +1 -0
- package/dist/services/local-file-storage.d.ts +56 -0
- package/dist/services/local-file-storage.d.ts.map +1 -0
- package/dist/services/local-file-storage.js +213 -0
- package/dist/services/local-file-storage.js.map +1 -0
- package/dist/services/local-vector-search.d.ts +137 -0
- package/dist/services/local-vector-search.d.ts.map +1 -0
- package/dist/services/local-vector-search.js +311 -0
- package/dist/services/local-vector-search.js.map +1 -0
- package/dist/services/metrics.d.ts +104 -0
- package/dist/services/metrics.d.ts.map +1 -0
- package/dist/services/metrics.js +264 -0
- package/dist/services/metrics.js.map +1 -0
- package/dist/services/session-state.d.ts +113 -0
- package/dist/services/session-state.d.ts.map +1 -0
- package/dist/services/session-state.js +203 -0
- package/dist/services/session-state.js.map +1 -0
- package/dist/services/startup.d.ts +112 -0
- package/dist/services/startup.d.ts.map +1 -0
- package/dist/services/startup.js +436 -0
- package/dist/services/startup.js.map +1 -0
- package/dist/services/storage.d.ts +43 -0
- package/dist/services/storage.d.ts.map +1 -0
- package/dist/services/storage.js +92 -0
- package/dist/services/storage.js.map +1 -0
- package/dist/services/supabase-client.d.ts +163 -0
- package/dist/services/supabase-client.d.ts.map +1 -0
- package/dist/services/supabase-client.js +510 -0
- package/dist/services/supabase-client.js.map +1 -0
- package/dist/services/thread-dedup.d.ts +44 -0
- package/dist/services/thread-dedup.d.ts.map +1 -0
- package/dist/services/thread-dedup.js +113 -0
- package/dist/services/thread-dedup.js.map +1 -0
- package/dist/services/thread-manager.d.ts +77 -0
- package/dist/services/thread-manager.d.ts.map +1 -0
- package/dist/services/thread-manager.js +250 -0
- package/dist/services/thread-manager.js.map +1 -0
- package/dist/services/thread-suggestions.d.ts +66 -0
- package/dist/services/thread-suggestions.d.ts.map +1 -0
- package/dist/services/thread-suggestions.js +243 -0
- package/dist/services/thread-suggestions.js.map +1 -0
- package/dist/services/thread-supabase.d.ts +111 -0
- package/dist/services/thread-supabase.d.ts.map +1 -0
- package/dist/services/thread-supabase.js +459 -0
- package/dist/services/thread-supabase.js.map +1 -0
- package/dist/services/thread-vitality.d.ts +65 -0
- package/dist/services/thread-vitality.d.ts.map +1 -0
- package/dist/services/thread-vitality.js +143 -0
- package/dist/services/thread-vitality.js.map +1 -0
- package/dist/services/tier.d.ts +52 -0
- package/dist/services/tier.d.ts.map +1 -0
- package/dist/services/tier.js +109 -0
- package/dist/services/tier.js.map +1 -0
- package/dist/services/timezone.d.ts +37 -0
- package/dist/services/timezone.d.ts.map +1 -0
- package/dist/services/timezone.js +147 -0
- package/dist/services/timezone.js.map +1 -0
- package/dist/services/transcript-chunker.d.ts +18 -0
- package/dist/services/transcript-chunker.d.ts.map +1 -0
- package/dist/services/transcript-chunker.js +237 -0
- package/dist/services/transcript-chunker.js.map +1 -0
- package/dist/services/triple-writer.d.ts +128 -0
- package/dist/services/triple-writer.d.ts.map +1 -0
- package/dist/services/triple-writer.js +338 -0
- package/dist/services/triple-writer.js.map +1 -0
- package/dist/services/variant-assignment.d.ts +92 -0
- package/dist/services/variant-assignment.d.ts.map +1 -0
- package/dist/services/variant-assignment.js +196 -0
- package/dist/services/variant-assignment.js.map +1 -0
- package/dist/tools/absorb-observations.d.ts +16 -0
- package/dist/tools/absorb-observations.d.ts.map +1 -0
- package/dist/tools/absorb-observations.js +82 -0
- package/dist/tools/absorb-observations.js.map +1 -0
- package/dist/tools/analyze.d.ts +55 -0
- package/dist/tools/analyze.d.ts.map +1 -0
- package/dist/tools/analyze.js +139 -0
- package/dist/tools/analyze.js.map +1 -0
- package/dist/tools/cleanup-threads.d.ts +47 -0
- package/dist/tools/cleanup-threads.d.ts.map +1 -0
- package/dist/tools/cleanup-threads.js +127 -0
- package/dist/tools/cleanup-threads.js.map +1 -0
- package/dist/tools/confirm-scars.d.ts +23 -0
- package/dist/tools/confirm-scars.d.ts.map +1 -0
- package/dist/tools/confirm-scars.js +209 -0
- package/dist/tools/confirm-scars.js.map +1 -0
- package/dist/tools/create-decision.d.ts +15 -0
- package/dist/tools/create-decision.d.ts.map +1 -0
- package/dist/tools/create-decision.js +138 -0
- package/dist/tools/create-decision.js.map +1 -0
- package/dist/tools/create-learning.d.ts +15 -0
- package/dist/tools/create-learning.d.ts.map +1 -0
- package/dist/tools/create-learning.js +226 -0
- package/dist/tools/create-learning.js.map +1 -0
- package/dist/tools/create-thread.d.ts +42 -0
- package/dist/tools/create-thread.d.ts.map +1 -0
- package/dist/tools/create-thread.js +180 -0
- package/dist/tools/create-thread.js.map +1 -0
- package/dist/tools/definitions.d.ts +5013 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +2017 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/dismiss-suggestion.d.ts +20 -0
- package/dist/tools/dismiss-suggestion.d.ts.map +1 -0
- package/dist/tools/dismiss-suggestion.js +40 -0
- package/dist/tools/dismiss-suggestion.js.map +1 -0
- package/dist/tools/get-transcript.d.ts +24 -0
- package/dist/tools/get-transcript.d.ts.map +1 -0
- package/dist/tools/get-transcript.js +52 -0
- package/dist/tools/get-transcript.js.map +1 -0
- package/dist/tools/graph-traverse.d.ts +83 -0
- package/dist/tools/graph-traverse.d.ts.map +1 -0
- package/dist/tools/graph-traverse.js +394 -0
- package/dist/tools/graph-traverse.js.map +1 -0
- package/dist/tools/list-threads.d.ts +15 -0
- package/dist/tools/list-threads.d.ts.map +1 -0
- package/dist/tools/list-threads.js +114 -0
- package/dist/tools/list-threads.js.map +1 -0
- package/dist/tools/log.d.ts +43 -0
- package/dist/tools/log.d.ts.map +1 -0
- package/dist/tools/log.js +157 -0
- package/dist/tools/log.js.map +1 -0
- package/dist/tools/prepare-context.d.ts +36 -0
- package/dist/tools/prepare-context.d.ts.map +1 -0
- package/dist/tools/prepare-context.js +353 -0
- package/dist/tools/prepare-context.js.map +1 -0
- package/dist/tools/promote-suggestion.d.ts +25 -0
- package/dist/tools/promote-suggestion.d.ts.map +1 -0
- package/dist/tools/promote-suggestion.js +60 -0
- package/dist/tools/promote-suggestion.js.map +1 -0
- package/dist/tools/recall.d.ts +77 -0
- package/dist/tools/recall.d.ts.map +1 -0
- package/dist/tools/recall.js +423 -0
- package/dist/tools/recall.js.map +1 -0
- package/dist/tools/recall.test.d.ts +5 -0
- package/dist/tools/recall.test.d.ts.map +1 -0
- package/dist/tools/recall.test.js +155 -0
- package/dist/tools/recall.test.js.map +1 -0
- package/dist/tools/record-scar-usage-batch.d.ts +10 -0
- package/dist/tools/record-scar-usage-batch.d.ts.map +1 -0
- package/dist/tools/record-scar-usage-batch.js +153 -0
- package/dist/tools/record-scar-usage-batch.js.map +1 -0
- package/dist/tools/record-scar-usage.d.ts +14 -0
- package/dist/tools/record-scar-usage.d.ts.map +1 -0
- package/dist/tools/record-scar-usage.js +94 -0
- package/dist/tools/record-scar-usage.js.map +1 -0
- package/dist/tools/resolve-thread.d.ts +16 -0
- package/dist/tools/resolve-thread.d.ts.map +1 -0
- package/dist/tools/resolve-thread.js +102 -0
- package/dist/tools/resolve-thread.js.map +1 -0
- package/dist/tools/save-transcript.d.ts +29 -0
- package/dist/tools/save-transcript.d.ts.map +1 -0
- package/dist/tools/save-transcript.js +97 -0
- package/dist/tools/save-transcript.js.map +1 -0
- package/dist/tools/search.d.ts +46 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +186 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/session-close.d.ts +14 -0
- package/dist/tools/session-close.d.ts.map +1 -0
- package/dist/tools/session-close.js +881 -0
- package/dist/tools/session-close.js.map +1 -0
- package/dist/tools/session-start.d.ts +38 -0
- package/dist/tools/session-start.d.ts.map +1 -0
- package/dist/tools/session-start.js +1104 -0
- package/dist/tools/session-start.js.map +1 -0
- package/dist/types/index.d.ts +456 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +76 -0
- package/schema/setup.sql +193 -0
- package/schema/starter-scars.json +206 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Triple Writer Service
|
|
3
|
+
*
|
|
4
|
+
* Phase 2: Rule-based extraction of knowledge triples from
|
|
5
|
+
* create_learning and create_decision operations.
|
|
6
|
+
*
|
|
7
|
+
* Design principles:
|
|
8
|
+
* - Fire-and-forget: never blocks the main tool response
|
|
9
|
+
* - High-confidence only: rule-based, no guessing
|
|
10
|
+
* - Uses directUpsert pattern from supabase-client.ts
|
|
11
|
+
*/
|
|
12
|
+
import { v4 as uuidv4 } from "uuid";
|
|
13
|
+
import * as supabase from "./supabase-client.js";
|
|
14
|
+
import { hasSupabase } from "./tier.js";
|
|
15
|
+
// --- Constants ---
|
|
16
|
+
/** Half-life profiles (days). Process = structural, never decays. */
|
|
17
|
+
const HALF_LIFE_PROCESS = 9999;
|
|
18
|
+
// --- Helpers ---
|
|
19
|
+
/**
|
|
20
|
+
* Canonical persona name map.
|
|
21
|
+
* Raw personas_involved values may contain full names or contextual suffixes.
|
|
22
|
+
* This ensures consistent node identity in the knowledge graph.
|
|
23
|
+
*/
|
|
24
|
+
const CANONICAL_PERSONA_NAMES = {
|
|
25
|
+
"elena vos": "Elena",
|
|
26
|
+
"elena": "Elena",
|
|
27
|
+
"marcus thorne": "Marcus",
|
|
28
|
+
"marcus": "Marcus",
|
|
29
|
+
"reiko tanaka": "Reiko",
|
|
30
|
+
"reiko": "Reiko",
|
|
31
|
+
"jax": "Jax",
|
|
32
|
+
"jax dimitri": "Jax",
|
|
33
|
+
"jax reed": "Jax",
|
|
34
|
+
"chris crawford": "Chris Crawford",
|
|
35
|
+
"chris": "Chris Crawford",
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Normalize a persona label to its canonical form.
|
|
39
|
+
* Strips contextual suffixes like " - UX navigation clarity" or ": Prefers non-invasive..."
|
|
40
|
+
* Then maps to canonical short name if known.
|
|
41
|
+
*
|
|
42
|
+
* Examples:
|
|
43
|
+
* "Elena Vos" → "Elena"
|
|
44
|
+
* "Marcus - Architectural pattern" → "Marcus"
|
|
45
|
+
* "Elena: Prefers non-invasive instrumentation" → "Elena"
|
|
46
|
+
* "Chris Crawford - Process decision" → "Chris Crawford"
|
|
47
|
+
*/
|
|
48
|
+
export function normalizePersonaLabel(raw) {
|
|
49
|
+
// Strip contextual suffix after " - " or ": "
|
|
50
|
+
let name = raw.split(" - ")[0].split(": ")[0].trim();
|
|
51
|
+
// Strip parenthetical role descriptions like "(Integration & Deployment)"
|
|
52
|
+
name = name.replace(/\s*\(.*?\)\s*$/, "").trim();
|
|
53
|
+
// Look up canonical name (case-insensitive)
|
|
54
|
+
const canonical = CANONICAL_PERSONA_NAMES[name.toLowerCase()];
|
|
55
|
+
return canonical || name;
|
|
56
|
+
}
|
|
57
|
+
/** Set of canonical persona names (Orchestra team members + human). */
|
|
58
|
+
const KNOWN_PERSONAS = new Set(Object.values(CANONICAL_PERSONA_NAMES));
|
|
59
|
+
/**
|
|
60
|
+
* Determine if a name refers to an Orchestra persona vs an agent.
|
|
61
|
+
* Returns true for Elena, Marcus, Reiko, Jax, Chris Crawford.
|
|
62
|
+
*/
|
|
63
|
+
function isPersonaName(name) {
|
|
64
|
+
return KNOWN_PERSONAS.has(normalizePersonaLabel(name));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Build a prefixed node label: "Persona: X" for known personas, "Agent: X" for agents.
|
|
68
|
+
* Normalizes persona names to canonical form.
|
|
69
|
+
*/
|
|
70
|
+
export function buildInfluencerLabel(rawName) {
|
|
71
|
+
const normalized = normalizePersonaLabel(rawName);
|
|
72
|
+
if (isPersonaName(normalized)) {
|
|
73
|
+
return `Persona: ${normalized}`;
|
|
74
|
+
}
|
|
75
|
+
return `Agent: ${rawName}`;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Build a human-readable subject label following the existing DB convention:
|
|
79
|
+
* "Win: Read-side enrichment pattern for denormalization gaps"
|
|
80
|
+
*/
|
|
81
|
+
function buildSubjectLabel(type, title) {
|
|
82
|
+
const typeLabels = {
|
|
83
|
+
scar: "Scar",
|
|
84
|
+
win: "Win",
|
|
85
|
+
pattern: "Pattern",
|
|
86
|
+
anti_pattern: "Anti-Pattern",
|
|
87
|
+
decision: "Decision",
|
|
88
|
+
thread: "Thread",
|
|
89
|
+
};
|
|
90
|
+
const label = typeLabels[type] || type.charAt(0).toUpperCase() + type.slice(1);
|
|
91
|
+
return `${label}: ${title}`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Extract triples from a newly created learning using rule-based logic.
|
|
95
|
+
* Pure function — no side effects.
|
|
96
|
+
*/
|
|
97
|
+
export function extractLearningTriples(params) {
|
|
98
|
+
const triples = [];
|
|
99
|
+
const subjectLabel = buildSubjectLabel(params.learning_type, params.title);
|
|
100
|
+
const base = {
|
|
101
|
+
source_type: "learning",
|
|
102
|
+
source_id: params.id,
|
|
103
|
+
source_linear_issue: params.source_linear_issue,
|
|
104
|
+
domain: params.domain,
|
|
105
|
+
project: params.project,
|
|
106
|
+
half_life_days: HALF_LIFE_PROCESS,
|
|
107
|
+
created_by: params.persona_name,
|
|
108
|
+
};
|
|
109
|
+
// RULE 1: source_linear_issue -> "created_in"
|
|
110
|
+
if (params.source_linear_issue) {
|
|
111
|
+
triples.push({
|
|
112
|
+
...base,
|
|
113
|
+
subject: subjectLabel,
|
|
114
|
+
predicate: "created_in",
|
|
115
|
+
object: `Issue: ${params.source_linear_issue}`,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
// RULE 2: persona_name -> "influenced_by"
|
|
119
|
+
if (params.persona_name && params.persona_name !== "Unknown") {
|
|
120
|
+
triples.push({
|
|
121
|
+
...base,
|
|
122
|
+
subject: subjectLabel,
|
|
123
|
+
predicate: "influenced_by",
|
|
124
|
+
object: buildInfluencerLabel(params.persona_name),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// RULE 3: Description contains "supersedes" with a reference
|
|
128
|
+
const supersedesMatch = params.description.match(/supersedes?\s+(?:scar|learning|pattern|win)?\s*[:\-]?\s*["']?([^"'\n.]{10,80})["']?/i);
|
|
129
|
+
if (supersedesMatch) {
|
|
130
|
+
triples.push({
|
|
131
|
+
...base,
|
|
132
|
+
subject: subjectLabel,
|
|
133
|
+
predicate: "supersedes",
|
|
134
|
+
object: supersedesMatch[1].trim(),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return triples;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Extract triples from a newly created decision using rule-based logic.
|
|
141
|
+
* Pure function — no side effects.
|
|
142
|
+
*/
|
|
143
|
+
export function extractDecisionTriples(params) {
|
|
144
|
+
const triples = [];
|
|
145
|
+
const subjectLabel = buildSubjectLabel("decision", params.title);
|
|
146
|
+
const base = {
|
|
147
|
+
source_type: "decision",
|
|
148
|
+
source_id: params.id,
|
|
149
|
+
source_linear_issue: params.linear_issue,
|
|
150
|
+
project: params.project,
|
|
151
|
+
half_life_days: HALF_LIFE_PROCESS,
|
|
152
|
+
created_by: params.agent,
|
|
153
|
+
};
|
|
154
|
+
// RULE 1: linear_issue -> "created_in"
|
|
155
|
+
if (params.linear_issue) {
|
|
156
|
+
triples.push({
|
|
157
|
+
...base,
|
|
158
|
+
subject: subjectLabel,
|
|
159
|
+
predicate: "created_in",
|
|
160
|
+
object: `Issue: ${params.linear_issue}`,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
// RULE 2: Each persona -> "influenced_by"
|
|
164
|
+
if (params.personas_involved?.length) {
|
|
165
|
+
const seen = new Set();
|
|
166
|
+
for (const persona of params.personas_involved) {
|
|
167
|
+
const label = buildInfluencerLabel(persona);
|
|
168
|
+
if (seen.has(label))
|
|
169
|
+
continue; // dedup after normalization
|
|
170
|
+
seen.add(label);
|
|
171
|
+
triples.push({
|
|
172
|
+
...base,
|
|
173
|
+
subject: subjectLabel,
|
|
174
|
+
predicate: "influenced_by",
|
|
175
|
+
object: label,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// RULE 3: Agent identity -> "influenced_by" (if not already covered by personas)
|
|
180
|
+
if (params.agent && params.agent !== "Unknown") {
|
|
181
|
+
const alreadyCovered = params.personas_involved?.some((p) => p.toLowerCase() === params.agent.toLowerCase());
|
|
182
|
+
if (!alreadyCovered) {
|
|
183
|
+
triples.push({
|
|
184
|
+
...base,
|
|
185
|
+
subject: subjectLabel,
|
|
186
|
+
predicate: "influenced_by",
|
|
187
|
+
object: `Agent: ${params.agent}`,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// RULE 4: Each doc in docs_affected -> "affects_doc"
|
|
192
|
+
if (params.docs_affected?.length) {
|
|
193
|
+
for (const doc of params.docs_affected) {
|
|
194
|
+
triples.push({
|
|
195
|
+
...base,
|
|
196
|
+
subject: subjectLabel,
|
|
197
|
+
predicate: "affects_doc",
|
|
198
|
+
object: `Doc: ${doc}`,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return triples;
|
|
203
|
+
}
|
|
204
|
+
// --- Write ---
|
|
205
|
+
/**
|
|
206
|
+
* Write triples to knowledge_triples table.
|
|
207
|
+
* Fire-and-forget: errors logged but never thrown to caller.
|
|
208
|
+
*/
|
|
209
|
+
export async function writeTriples(candidates) {
|
|
210
|
+
if (candidates.length === 0 || !hasSupabase()) {
|
|
211
|
+
return 0;
|
|
212
|
+
}
|
|
213
|
+
let written = 0;
|
|
214
|
+
for (const candidate of candidates) {
|
|
215
|
+
try {
|
|
216
|
+
await supabase.directUpsert("knowledge_triples", {
|
|
217
|
+
id: uuidv4(),
|
|
218
|
+
subject: candidate.subject,
|
|
219
|
+
predicate: candidate.predicate,
|
|
220
|
+
object: candidate.object,
|
|
221
|
+
event_time: new Date().toISOString(),
|
|
222
|
+
decay_weight: 1.0,
|
|
223
|
+
half_life_days: candidate.half_life_days,
|
|
224
|
+
decay_floor: 0.1,
|
|
225
|
+
source_type: candidate.source_type,
|
|
226
|
+
source_id: candidate.source_id,
|
|
227
|
+
source_linear_issue: candidate.source_linear_issue || null,
|
|
228
|
+
domain: candidate.domain || [],
|
|
229
|
+
project: candidate.project,
|
|
230
|
+
created_at: new Date().toISOString(),
|
|
231
|
+
updated_at: new Date().toISOString(),
|
|
232
|
+
created_by: candidate.created_by,
|
|
233
|
+
});
|
|
234
|
+
written++;
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
console.error(`[triple-writer] Failed to write triple: ${candidate.subject} ${candidate.predicate} ${candidate.object}`, error instanceof Error ? error.message : error);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (written > 0) {
|
|
241
|
+
console.error(`[triple-writer] Wrote ${written}/${candidates.length} triples`);
|
|
242
|
+
}
|
|
243
|
+
return written;
|
|
244
|
+
}
|
|
245
|
+
// --- Public API ---
|
|
246
|
+
/**
|
|
247
|
+
* Generate and write triples for a newly created learning.
|
|
248
|
+
* Fire-and-forget — call with .catch(() => {}).
|
|
249
|
+
*/
|
|
250
|
+
export function writeTriplesForLearning(params) {
|
|
251
|
+
const triples = extractLearningTriples(params);
|
|
252
|
+
return writeTriples(triples);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Generate and write triples for a newly created decision.
|
|
256
|
+
* Fire-and-forget — call with .catch(() => {}).
|
|
257
|
+
*/
|
|
258
|
+
export function writeTriplesForDecision(params) {
|
|
259
|
+
const triples = extractDecisionTriples(params);
|
|
260
|
+
return writeTriples(triples);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Extract triples from a newly created thread.
|
|
264
|
+
* Pure function — no side effects.
|
|
265
|
+
*/
|
|
266
|
+
export function extractThreadCreationTriples(params) {
|
|
267
|
+
const triples = [];
|
|
268
|
+
const threadLabel = buildSubjectLabel("thread", params.text);
|
|
269
|
+
const base = {
|
|
270
|
+
source_type: "thread",
|
|
271
|
+
source_id: params.thread_id,
|
|
272
|
+
source_linear_issue: params.linear_issue,
|
|
273
|
+
project: params.project,
|
|
274
|
+
half_life_days: HALF_LIFE_PROCESS,
|
|
275
|
+
created_by: params.agent,
|
|
276
|
+
};
|
|
277
|
+
// RULE 1: session_id -> "created_thread" (Session created this thread)
|
|
278
|
+
if (params.session_id) {
|
|
279
|
+
triples.push({
|
|
280
|
+
...base,
|
|
281
|
+
subject: `Session: ${params.session_id}`,
|
|
282
|
+
predicate: "created_thread",
|
|
283
|
+
object: threadLabel,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
// RULE 2: linear_issue -> "relates_to_thread" (Thread relates to issue)
|
|
287
|
+
if (params.linear_issue) {
|
|
288
|
+
triples.push({
|
|
289
|
+
...base,
|
|
290
|
+
subject: threadLabel,
|
|
291
|
+
predicate: "relates_to_thread",
|
|
292
|
+
object: `Issue: ${params.linear_issue}`,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
return triples;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Extract triples from a resolved thread.
|
|
299
|
+
* Pure function — no side effects.
|
|
300
|
+
*/
|
|
301
|
+
export function extractThreadResolutionTriples(params) {
|
|
302
|
+
const triples = [];
|
|
303
|
+
const threadLabel = buildSubjectLabel("thread", params.text);
|
|
304
|
+
const base = {
|
|
305
|
+
source_type: "thread",
|
|
306
|
+
source_id: params.thread_id,
|
|
307
|
+
project: params.project,
|
|
308
|
+
half_life_days: HALF_LIFE_PROCESS,
|
|
309
|
+
created_by: params.agent,
|
|
310
|
+
};
|
|
311
|
+
// RULE 1: session_id -> "resolves_thread" (Session resolved this thread)
|
|
312
|
+
if (params.session_id) {
|
|
313
|
+
triples.push({
|
|
314
|
+
...base,
|
|
315
|
+
subject: `Session: ${params.session_id}`,
|
|
316
|
+
predicate: "resolves_thread",
|
|
317
|
+
object: threadLabel,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
return triples;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Generate and write triples for a newly created thread.
|
|
324
|
+
* Fire-and-forget — call with .catch(() => {}).
|
|
325
|
+
*/
|
|
326
|
+
export function writeTriplesForThreadCreation(params) {
|
|
327
|
+
const triples = extractThreadCreationTriples(params);
|
|
328
|
+
return writeTriples(triples);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Generate and write triples for a resolved thread.
|
|
332
|
+
* Fire-and-forget — call with .catch(() => {}).
|
|
333
|
+
*/
|
|
334
|
+
export function writeTriplesForThreadResolution(params) {
|
|
335
|
+
const triples = extractThreadResolutionTriples(params);
|
|
336
|
+
return writeTriples(triples);
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=triple-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triple-writer.js","sourceRoot":"","sources":["../../src/services/triple-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scar Variant Assignment Service
|
|
3
|
+
* OD-525: Integrates variant assignment into enforcement engine
|
|
4
|
+
* OD-547: Switched from issue-keyed to agent-keyed assignment
|
|
5
|
+
*
|
|
6
|
+
* Handles:
|
|
7
|
+
* - Random variant assignment for scars with variants
|
|
8
|
+
* - Idempotent assignment (same agent+scar always gets same variant)
|
|
9
|
+
* - Legacy scar fallback (scars without variants use original description)
|
|
10
|
+
* - Blind testing (agent doesn't know which variant they received)
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Variant record from database
|
|
14
|
+
*/
|
|
15
|
+
export interface ScarVariant {
|
|
16
|
+
id: string;
|
|
17
|
+
variant_name: string;
|
|
18
|
+
variant_version: string;
|
|
19
|
+
description: string;
|
|
20
|
+
enforcement_config: {
|
|
21
|
+
type: "imperative" | "declarative";
|
|
22
|
+
show_counter_arguments?: boolean;
|
|
23
|
+
steps?: string[];
|
|
24
|
+
success_state?: string;
|
|
25
|
+
verification_tests?: string[];
|
|
26
|
+
constraints?: string[];
|
|
27
|
+
};
|
|
28
|
+
active: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Assignment record
|
|
32
|
+
* OD-547: Primary key is (agent_id, scar_id), issue_id/session_id are metadata
|
|
33
|
+
*/
|
|
34
|
+
export interface VariantAssignment {
|
|
35
|
+
id: string;
|
|
36
|
+
agent_id: string;
|
|
37
|
+
scar_id: string;
|
|
38
|
+
variant_id: string;
|
|
39
|
+
assigned_at: string;
|
|
40
|
+
issue_id?: string;
|
|
41
|
+
session_id?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Result of variant retrieval for a scar
|
|
45
|
+
*/
|
|
46
|
+
export interface ScarWithVariant {
|
|
47
|
+
scar_id: string;
|
|
48
|
+
has_variants: boolean;
|
|
49
|
+
variant?: ScarVariant;
|
|
50
|
+
assignment?: VariantAssignment;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get active variants for a scar
|
|
54
|
+
*/
|
|
55
|
+
export declare function getActiveVariants(scarId: string): Promise<ScarVariant[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Get existing assignment for an agent + scar pair
|
|
58
|
+
* OD-547: Changed from issue-keyed to agent-keyed lookup
|
|
59
|
+
*/
|
|
60
|
+
export declare function getExistingAssignment(agentId: string, scarId: string): Promise<VariantAssignment | null>;
|
|
61
|
+
/**
|
|
62
|
+
* Create random variant assignment
|
|
63
|
+
* OD-547: Agent-keyed with optional issue/session metadata
|
|
64
|
+
*/
|
|
65
|
+
export declare function createVariantAssignment(agentId: string, scarId: string, variants: ScarVariant[], metadata?: {
|
|
66
|
+
issueId?: string;
|
|
67
|
+
sessionId?: string;
|
|
68
|
+
}): Promise<VariantAssignment | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Get or create variant assignment for a scar
|
|
71
|
+
* This is the main entry point for enforcement integration
|
|
72
|
+
*
|
|
73
|
+
* OD-547: Changed from issue-keyed to agent-keyed assignment.
|
|
74
|
+
* Agent identity is always available, so variants are always assigned.
|
|
75
|
+
*
|
|
76
|
+
* @param agentId - Agent identity (e.g., 'CLI', 'DAC', 'CODA-1')
|
|
77
|
+
* @param scarId - UUID of the scar
|
|
78
|
+
* @param metadata - Optional issue_id and session_id for triple traversals
|
|
79
|
+
* @returns Scar with variant info, or has_variants=false for legacy scars
|
|
80
|
+
*/
|
|
81
|
+
export declare function getOrAssignVariant(agentId: string, scarId: string, metadata?: {
|
|
82
|
+
issueId?: string;
|
|
83
|
+
sessionId?: string;
|
|
84
|
+
}): Promise<ScarWithVariant>;
|
|
85
|
+
/**
|
|
86
|
+
* Format enforcement text based on variant type
|
|
87
|
+
* Returns formatted description with variant-specific structure
|
|
88
|
+
*
|
|
89
|
+
* This is BLIND - agent never sees variant name or type indicator
|
|
90
|
+
*/
|
|
91
|
+
export declare function formatVariantEnforcement(variant: ScarVariant, scarTitle: string): string;
|
|
92
|
+
//# sourceMappingURL=variant-assignment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variant-assignment.d.ts","sourceRoot":"","sources":["../../src/services/variant-assignment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE;QAClB,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC;QACnC,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC9B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAuB9E;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAwBnC;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,WAAW,EAAE,EACvB,QAAQ,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAkCnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD,OAAO,CAAC,eAAe,CAAC,CA4C1B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmDxF"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scar Variant Assignment Service
|
|
3
|
+
* OD-525: Integrates variant assignment into enforcement engine
|
|
4
|
+
* OD-547: Switched from issue-keyed to agent-keyed assignment
|
|
5
|
+
*
|
|
6
|
+
* Handles:
|
|
7
|
+
* - Random variant assignment for scars with variants
|
|
8
|
+
* - Idempotent assignment (same agent+scar always gets same variant)
|
|
9
|
+
* - Legacy scar fallback (scars without variants use original description)
|
|
10
|
+
* - Blind testing (agent doesn't know which variant they received)
|
|
11
|
+
*/
|
|
12
|
+
import * as supabase from "./supabase-client.js";
|
|
13
|
+
/**
|
|
14
|
+
* Get active variants for a scar
|
|
15
|
+
*/
|
|
16
|
+
export async function getActiveVariants(scarId) {
|
|
17
|
+
if (!supabase.isConfigured()) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
// Use directQuery to bypass ww-mcp and query Supabase REST API directly
|
|
22
|
+
const variants = await supabase.directQuery("scar_enforcement_variants", {
|
|
23
|
+
select: "*",
|
|
24
|
+
filters: {
|
|
25
|
+
scar_id: scarId,
|
|
26
|
+
active: "true",
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
return variants;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error(`[variant-assignment] Exception fetching variants:`, error);
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get existing assignment for an agent + scar pair
|
|
38
|
+
* OD-547: Changed from issue-keyed to agent-keyed lookup
|
|
39
|
+
*/
|
|
40
|
+
export async function getExistingAssignment(agentId, scarId) {
|
|
41
|
+
if (!supabase.isConfigured()) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const assignments = await supabase.directQuery("variant_assignments", {
|
|
46
|
+
select: "*",
|
|
47
|
+
filters: {
|
|
48
|
+
agent_id: agentId,
|
|
49
|
+
},
|
|
50
|
+
limit: 10,
|
|
51
|
+
});
|
|
52
|
+
// Filter by scar_id locally
|
|
53
|
+
const match = assignments.find(a => a.scar_id === scarId);
|
|
54
|
+
return match || null;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error(`[variant-assignment] Exception fetching assignment:`, error);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create random variant assignment
|
|
63
|
+
* OD-547: Agent-keyed with optional issue/session metadata
|
|
64
|
+
*/
|
|
65
|
+
export async function createVariantAssignment(agentId, scarId, variants, metadata) {
|
|
66
|
+
if (!supabase.isConfigured() || variants.length === 0) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
// Random selection from active variants
|
|
71
|
+
const randomIndex = Math.floor(Math.random() * variants.length);
|
|
72
|
+
const selectedVariant = variants[randomIndex];
|
|
73
|
+
const result = await supabase.directUpsert("variant_assignments", {
|
|
74
|
+
agent_id: agentId,
|
|
75
|
+
scar_id: scarId,
|
|
76
|
+
variant_id: selectedVariant.id,
|
|
77
|
+
issue_id: metadata?.issueId || null,
|
|
78
|
+
session_id: metadata?.sessionId || null,
|
|
79
|
+
});
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
84
|
+
// Handle race condition: unique constraint violation
|
|
85
|
+
if (errorMessage.includes("23505") || errorMessage.includes("duplicate key")) {
|
|
86
|
+
console.error(`[variant-assignment] Assignment already exists (race condition), fetching...`);
|
|
87
|
+
return await getExistingAssignment(agentId, scarId);
|
|
88
|
+
}
|
|
89
|
+
console.error(`[variant-assignment] Exception creating assignment:`, error);
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get or create variant assignment for a scar
|
|
95
|
+
* This is the main entry point for enforcement integration
|
|
96
|
+
*
|
|
97
|
+
* OD-547: Changed from issue-keyed to agent-keyed assignment.
|
|
98
|
+
* Agent identity is always available, so variants are always assigned.
|
|
99
|
+
*
|
|
100
|
+
* @param agentId - Agent identity (e.g., 'CLI', 'DAC', 'CODA-1')
|
|
101
|
+
* @param scarId - UUID of the scar
|
|
102
|
+
* @param metadata - Optional issue_id and session_id for triple traversals
|
|
103
|
+
* @returns Scar with variant info, or has_variants=false for legacy scars
|
|
104
|
+
*/
|
|
105
|
+
export async function getOrAssignVariant(agentId, scarId, metadata) {
|
|
106
|
+
// Step 1: Check for active variants
|
|
107
|
+
const variants = await getActiveVariants(scarId);
|
|
108
|
+
if (variants.length === 0) {
|
|
109
|
+
// Legacy scar - no variants available
|
|
110
|
+
return {
|
|
111
|
+
scar_id: scarId,
|
|
112
|
+
has_variants: false,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// Step 2: Check for existing assignment (idempotent per agent+scar)
|
|
116
|
+
let assignment = await getExistingAssignment(agentId, scarId);
|
|
117
|
+
// Step 3: Create assignment if it doesn't exist
|
|
118
|
+
if (!assignment) {
|
|
119
|
+
assignment = await createVariantAssignment(agentId, scarId, variants, metadata);
|
|
120
|
+
if (!assignment) {
|
|
121
|
+
// Assignment failed, fall back to legacy mode
|
|
122
|
+
return {
|
|
123
|
+
scar_id: scarId,
|
|
124
|
+
has_variants: false,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Step 4: Find the assigned variant
|
|
129
|
+
const variant = variants.find((v) => v.id === assignment.variant_id);
|
|
130
|
+
if (!variant) {
|
|
131
|
+
console.error(`[variant-assignment] Variant ${assignment.variant_id} not found in active variants`);
|
|
132
|
+
return {
|
|
133
|
+
scar_id: scarId,
|
|
134
|
+
has_variants: false,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
scar_id: scarId,
|
|
139
|
+
has_variants: true,
|
|
140
|
+
variant,
|
|
141
|
+
assignment,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Format enforcement text based on variant type
|
|
146
|
+
* Returns formatted description with variant-specific structure
|
|
147
|
+
*
|
|
148
|
+
* This is BLIND - agent never sees variant name or type indicator
|
|
149
|
+
*/
|
|
150
|
+
export function formatVariantEnforcement(variant, scarTitle) {
|
|
151
|
+
const config = variant.enforcement_config;
|
|
152
|
+
if (config.type === "imperative") {
|
|
153
|
+
// Traditional format: imperative steps
|
|
154
|
+
const lines = [];
|
|
155
|
+
if (config.steps && config.steps.length > 0) {
|
|
156
|
+
for (const step of config.steps) {
|
|
157
|
+
lines.push(step);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Fallback to description if no steps
|
|
162
|
+
lines.push(variant.description);
|
|
163
|
+
}
|
|
164
|
+
return lines.join("\n\n");
|
|
165
|
+
}
|
|
166
|
+
else if (config.type === "declarative") {
|
|
167
|
+
// Karpathy format: success state + verification tests + constraints
|
|
168
|
+
const lines = [];
|
|
169
|
+
if (config.success_state) {
|
|
170
|
+
lines.push("## Success State");
|
|
171
|
+
lines.push("");
|
|
172
|
+
lines.push(config.success_state);
|
|
173
|
+
lines.push("");
|
|
174
|
+
}
|
|
175
|
+
if (config.verification_tests && config.verification_tests.length > 0) {
|
|
176
|
+
lines.push("## Verification Tests");
|
|
177
|
+
lines.push("");
|
|
178
|
+
for (const test of config.verification_tests) {
|
|
179
|
+
lines.push(`- ${test}`);
|
|
180
|
+
}
|
|
181
|
+
lines.push("");
|
|
182
|
+
}
|
|
183
|
+
if (config.constraints && config.constraints.length > 0) {
|
|
184
|
+
lines.push("## Constraints");
|
|
185
|
+
lines.push("");
|
|
186
|
+
for (const constraint of config.constraints) {
|
|
187
|
+
lines.push(`- ${constraint}`);
|
|
188
|
+
}
|
|
189
|
+
lines.push("");
|
|
190
|
+
}
|
|
191
|
+
return lines.join("\n");
|
|
192
|
+
}
|
|
193
|
+
// Fallback
|
|
194
|
+
return variant.description;
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=variant-assignment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variant-assignment.js","sourceRoot":"","sources":["../../src/services/variant-assignment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* absorb_observations Tool (GitMem v2 Phase 2)
|
|
3
|
+
*
|
|
4
|
+
* Captures observations from sub-agents and teammates.
|
|
5
|
+
* The lead agent parses findings from sub-agent responses,
|
|
6
|
+
* then calls this tool to persist and analyze them.
|
|
7
|
+
*
|
|
8
|
+
* Identifies scar candidates via explicit severity or pattern matching.
|
|
9
|
+
* Observations are stored in-memory (session state) and optionally
|
|
10
|
+
* persisted to Supabase as a fire-and-forget upsert.
|
|
11
|
+
*
|
|
12
|
+
* Performance target: <500ms (in-memory + optional upsert)
|
|
13
|
+
*/
|
|
14
|
+
import type { AbsorbObservationsParams, AbsorbObservationsResult } from "../types/index.js";
|
|
15
|
+
export declare function absorbObservations(params: AbsorbObservationsParams): Promise<AbsorbObservationsResult>;
|
|
16
|
+
//# sourceMappingURL=absorb-observations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"absorb-observations.d.ts","sourceRoot":"","sources":["../../src/tools/absorb-observations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH,OAAO,KAAK,EAAE,wBAAwB,EAAE,wBAAwB,EAAe,MAAM,mBAAmB,CAAC;AA2BzG,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,wBAAwB,CAAC,CA+CnC"}
|