opencode-wait-a-minute 0.0.0-stage → 1.1.0-rc.10
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/LICENSE +21 -0
- package/README.md +318 -2
- package/index.js +1836 -0
- package/package.json +70 -4
- package/skills/codebase-design/SKILL.md +114 -0
- package/skills/design-contract/SKILL.md +27 -0
- package/skills/design-critique/SKILL.md +19 -0
- package/skills/design-system/SKILL.md +17 -0
- package/skills/design-system/references/image-analysis.md +14 -0
- package/skills/design-system/references/tokens.md +32 -0
- package/skills/design-system/references/ui-rules.md +14 -0
- package/skills/diagnosing-bugs/SKILL.md +138 -0
- package/skills/frontend-design/SKILL.md +36 -0
- package/skills/handoff/SKILL.md +16 -0
- package/skills/improve-codebase-architecture/SKILL.md +71 -0
- package/skills/linter-negative/SKILL.md +74 -0
- package/skills/no-slop-ui/SKILL.md +26 -0
- package/skills/prototype/SKILL.md +26 -0
- package/skills/registry.json +44087 -0
- package/skills/tastemaker/SKILL.md +8 -0
- package/skills/tastemaker/references/tastemaker.md +14 -0
- package/skills/tdd/SKILL.md +38 -0
- package/skills/visual-review/SKILL.md +103 -0
- package/skills/visual-review/references/review-gates.md +42 -0
- package/skills/visual-review/references/surface-archetypes.md +37 -0
- package/skills/wizard/SKILL.md +44 -0
- package/skills/writing-for-agents/SKILL.md +81 -0
- package/src/cognition/cognition-store.js +251 -0
- package/src/cognition/cognitive-state.js +126 -0
- package/src/cognition/hypothesis-manager.js +113 -0
- package/src/cognition/observation-engine.js +112 -0
- package/src/cognition/observation-provenance.js +268 -0
- package/src/context/active-context-boundary.js +68 -0
- package/src/context/assembly.js +494 -0
- package/src/context/assessment-rules.js +55 -0
- package/src/context/capsule-staleness.js +267 -0
- package/src/context/capsules.js +2 -0
- package/src/context/compare-array.js +98 -0
- package/src/context/compare-object.js +89 -0
- package/src/context/compare-values.js +42 -0
- package/src/context/context-assembly-contract.js +71 -0
- package/src/context/context-budget-manager.js +232 -0
- package/src/context/context-builder.js +49 -0
- package/src/context/context-cache.js +55 -0
- package/src/context/context-capture.js +243 -0
- package/src/context/context-classification.js +199 -0
- package/src/context/context-compaction.js +179 -0
- package/src/context/context-decision-audit.js +267 -0
- package/src/context/context-demotion.js +173 -0
- package/src/context/context-dictionary.js +106 -0
- package/src/context/context-drift-detection.js +225 -0
- package/src/context/context-evaluation.js +374 -0
- package/src/context/context-event-ingress.js +100 -0
- package/src/context/context-event-normalization.js +224 -0
- package/src/context/context-feedback-loop.js +216 -0
- package/src/context/context-freshness.js +21 -0
- package/src/context/context-graph-builder.js +71 -0
- package/src/context/context-graph.js +451 -0
- package/src/context/context-history-relevance.js +321 -0
- package/src/context/context-interception.js +145 -0
- package/src/context/context-invalidation-events.js +154 -0
- package/src/context/context-lifecycle.js +170 -0
- package/src/context/context-loop-prevention.js +347 -0
- package/src/context/context-manager.js +340 -0
- package/src/context/context-memory-layers.js +265 -0
- package/src/context/context-minimality.js +166 -0
- package/src/context/context-normalization.js +130 -0
- package/src/context/context-optimization-metrics.js +434 -0
- package/src/context/context-output-policy.js +135 -0
- package/src/context/context-pack-authority.js +157 -0
- package/src/context/context-promotion.js +172 -0
- package/src/context/context-query-contract.js +101 -0
- package/src/context/context-ranking.js +164 -0
- package/src/context/context-rate-distortion.js +261 -0
- package/src/context/context-recovery.js +209 -0
- package/src/context/context-retrieval-integration.js +60 -0
- package/src/context/context-retrieval.js +93 -0
- package/src/context/context-router.js +457 -0
- package/src/context/context-routing-evaluation.js +331 -0
- package/src/context/context-routing-observability.js +296 -0
- package/src/context/context-routing-shadow.js +237 -0
- package/src/context/context-scope.js +181 -0
- package/src/context/context-snapshot.js +226 -0
- package/src/context/context-source-registry.js +95 -0
- package/src/context/context-sufficiency-gate.js +120 -0
- package/src/context/context-sufficiency-oracle.js +167 -0
- package/src/context/context-telemetry.js +176 -0
- package/src/context/context.js +633 -0
- package/src/context/dependency-closure.js +246 -0
- package/src/context/page-fault-tracker.js +275 -0
- package/src/context/prompt-engine.js +74 -0
- package/src/context/runtime-context-graph.js +260 -0
- package/src/context/selection.js +2 -0
- package/src/context/session.js +2 -0
- package/src/context/sufficiency-contract.js +300 -0
- package/src/context/tokenizer.js +17 -0
- package/src/context-benchmark-router.mjs +125 -0
- package/src/evidence/evidence-engine.js +161 -0
- package/src/evidence/evidence-factory.js +3 -0
- package/src/evidence/evidence-freshness.js +463 -0
- package/src/evidence/evidence-gap.js +76 -0
- package/src/evidence/evidence-lineage.js +525 -0
- package/src/evidence/evidence.js +136 -0
- package/src/evidence/freshness-validation.js +187 -0
- package/src/evidence/lineage.js +4 -0
- package/src/execution/action-evaluation.js +179 -0
- package/src/execution/circuit-breaker.js +70 -0
- package/src/execution/claim-interception.js +63 -0
- package/src/execution/execution-engine.js +258 -0
- package/src/execution/execution-intent.js +69 -0
- package/src/execution/execution-state.js +89 -0
- package/src/execution/formatting.js +60 -0
- package/src/execution/l1-sanitize.js +16 -0
- package/src/execution/l2-resource-guards.js +19 -0
- package/src/execution/l3-invariant-checker.js +5 -0
- package/src/execution/l4-containment.js +6 -0
- package/src/execution/runtime-guards.js +106 -0
- package/src/execution/strategy-identity.js +162 -0
- package/src/execution/tool-interceptor.js +7 -0
- package/src/execution/tool-result-classifier.js +63 -0
- package/src/integration/canary-deploy.js +143 -0
- package/src/integration/collector.js +59 -0
- package/src/integration/error-recovery.js +6 -0
- package/src/integration/event-bus.js +66 -0
- package/src/integration/health-checker.js +57 -0
- package/src/integration/logger.js +39 -0
- package/src/integration/message-handler.js +611 -0
- package/src/integration/opencode-db.js +153 -0
- package/src/integration/orchestration.js +419 -0
- package/src/integration/part-provenance.js +65 -0
- package/src/integration/rate-limiter.js +55 -0
- package/src/integration/release-gate.js +336 -0
- package/src/integration/rollback-manager.js +164 -0
- package/src/integration/router-adapter.js +269 -0
- package/src/integration/telemetry.js +45 -0
- package/src/integration/update-checker.js +10 -0
- package/src/persistence/event-sourcing.js +75 -0
- package/src/persistence/memory.js +501 -0
- package/src/persistence/migration-runner.js +16 -0
- package/src/persistence/persistence-manager.js +39 -0
- package/src/persistence/transaction-log.js +157 -0
- package/src/policy/action-capabilities.js +116 -0
- package/src/policy/action-policy.js +4 -0
- package/src/policy/assessment-engine.js +104 -0
- package/src/policy/assumption-tracking.js +66 -0
- package/src/policy/budget-enforcer.js +7 -0
- package/src/policy/config-validator.js +102 -0
- package/src/policy/execution-assessment.js +142 -0
- package/src/policy/failure-classification.js +5 -0
- package/src/policy/feature-flags.js +65 -0
- package/src/policy/governance-enforcement.js +118 -0
- package/src/policy/locale.js +15 -0
- package/src/policy/multi-signer.js +151 -0
- package/src/policy/policy-state-machine.js +97 -0
- package/src/policy/ponytail-constraint.js +38 -0
- package/src/policy/project-inspector.js +93 -0
- package/src/policy/query-builder.js +14 -0
- package/src/policy/request-classifier.js +79 -0
- package/src/policy/risk-engine.js +266 -0
- package/src/policy/scope-enforcement.js +140 -0
- package/src/policy/secret-scanner.js +68 -0
- package/src/policy/skill-routing.js +104 -0
- package/src/policy/strategy-capabilities.js +211 -0
- package/src/policy/strategy.js +6 -0
- package/src/policy/uncertainty.js +117 -0
- package/src/shared/container.js +44 -0
- package/src/shared/decision-types.js +24 -0
- package/src/shared/simple-test.js +160 -0
- package/src/shared/wam-events.js +52 -0
- package/src/skills/engine.js +1705 -0
- package/src/skills/skill-registry.js +19 -0
- package/src/skills/skill-routing.js +340 -0
- package/src/state/lifecycle-manager.js +113 -0
- package/src/state/operational-state.js +198 -0
- package/src/state/projections.js +47 -0
- package/src/state/replay-engine.js +5 -0
- package/src/state/requirement-ownership.js +20 -0
- package/src/state/requirement-state.js +152 -0
- package/src/state/run-event-identity.js +172 -0
- package/src/state/state-engine.js +19 -0
- package/src/state/state-machine.js +119 -0
- package/src/state/state-schema.js +318 -0
- package/src/state/state-store.js +335 -0
- package/src/state/state-transition.js +84 -0
- package/src/state/task-dependencies.js +287 -0
- package/src/state/task-execution.js +217 -0
- package/src/state/task-lifecycle.js +59 -0
- package/src/state/task-runs.js +361 -0
- package/src/state/task-state-file.js +86 -0
- package/src/state/task-state.js +41 -0
- package/src/state/task-status.js +54 -0
- package/src/state/task-store.js +48 -0
- package/src/state/wam-state.js +148 -0
- package/src/verification/completion-gate-simple.js +8 -0
- package/src/verification/completion-gate.js +183 -0
- package/src/verification/contract.js +9 -0
- package/src/verification/contradiction-resolution.js +255 -0
- package/src/verification/diagnostic-engine.js +659 -0
- package/src/verification/false-completion-prevention.js +100 -0
- package/src/verification/hook-validator.js +6 -0
- package/src/verification/requirements.js +6 -0
- package/src/verification/verification-context.js +162 -0
- package/src/verification/verification-lifecycle.js +66 -0
- package/src/verification/verification-model.js +89 -0
- package/src/verification/verification-persistence.js +129 -0
- package/src/verification/verification-policy.js +127 -0
- package/src/verification/verification.js +415 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Feedback Loop — Telemetry for learning from useful/useless retrievals.
|
|
3
|
+
*
|
|
4
|
+
* Change 77: Records retrieval outcomes (useful/useless) and adapts
|
|
5
|
+
* future context selection based on historical effectiveness.
|
|
6
|
+
*
|
|
7
|
+
* Metrics tracked:
|
|
8
|
+
* - Retrieval success rate per source/type
|
|
9
|
+
* - Per-item usefulness score
|
|
10
|
+
* - Drift indicators (repeated useless retrievals)
|
|
11
|
+
*
|
|
12
|
+
* All data in-memory, deterministic. No external dependencies.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {Object} RetrievalEvent
|
|
17
|
+
* @property {string} queryId - Identifier for the query/request
|
|
18
|
+
* @property {string} itemId - The context item retrieved
|
|
19
|
+
* @property {string} source - Source of the item
|
|
20
|
+
* @property {string} type - Type of the item
|
|
21
|
+
* @property {boolean} useful - Whether the item was actually useful
|
|
22
|
+
* @property {number} timestamp - Unix ms
|
|
23
|
+
* @property {string} [reason] - Optional reason for the rating
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {Object} SourceStats
|
|
28
|
+
* @property {number} total - Total retrievals from this source
|
|
29
|
+
* @property {number} useful - How many were rated useful
|
|
30
|
+
* @property {number} useless - How many were rated useless
|
|
31
|
+
* @property {number} score - useful / total (0-1)
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {Object} ItemStats
|
|
36
|
+
* @property {number} total - Times retrieved
|
|
37
|
+
* @property {number} useful - Times rated useful
|
|
38
|
+
* @property {number} lastUsed - Last timestamp
|
|
39
|
+
* @property {number} score - useful / total
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
class FeedbackLoop {
|
|
43
|
+
constructor() {
|
|
44
|
+
/** @type {RetrievalEvent[]} */
|
|
45
|
+
this._events = [];
|
|
46
|
+
/** @type {Map<string, ItemStats>} */
|
|
47
|
+
this._itemStats = new Map();
|
|
48
|
+
/** @type {Map<string, SourceStats>} */
|
|
49
|
+
this._sourceStats = new Map();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Record a retrieval outcome.
|
|
54
|
+
* @param {RetrievalEvent} event
|
|
55
|
+
*/
|
|
56
|
+
record(event) {
|
|
57
|
+
if (!event || !event.itemId || !event.queryId) {
|
|
58
|
+
throw new TypeError("Event must have itemId and queryId");
|
|
59
|
+
}
|
|
60
|
+
if (typeof event.useful !== "boolean") {
|
|
61
|
+
throw new TypeError("Event must have boolean useful field");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const timestamp = event.timestamp || Date.now();
|
|
65
|
+
const enriched = { ...event, timestamp };
|
|
66
|
+
this._events.push(enriched);
|
|
67
|
+
|
|
68
|
+
// Update item stats
|
|
69
|
+
const itemKey = event.itemId;
|
|
70
|
+
const itemStats = this._itemStats.get(itemKey) || {
|
|
71
|
+
total: 0, useful: 0, useless: 0, lastUsed: 0, score: 0,
|
|
72
|
+
};
|
|
73
|
+
itemStats.total++;
|
|
74
|
+
if (event.useful) {
|
|
75
|
+
itemStats.useful++;
|
|
76
|
+
} else {
|
|
77
|
+
itemStats.useless++;
|
|
78
|
+
}
|
|
79
|
+
itemStats.lastUsed = timestamp;
|
|
80
|
+
itemStats.score = itemStats.useful / itemStats.total;
|
|
81
|
+
this._itemStats.set(itemKey, itemStats);
|
|
82
|
+
|
|
83
|
+
// Update source stats
|
|
84
|
+
const srcKey = event.source || "unknown";
|
|
85
|
+
const srcStats = this._sourceStats.get(srcKey) || {
|
|
86
|
+
total: 0, useful: 0, useless: 0, score: 0,
|
|
87
|
+
};
|
|
88
|
+
srcStats.total++;
|
|
89
|
+
if (event.useful) {
|
|
90
|
+
srcStats.useful++;
|
|
91
|
+
} else {
|
|
92
|
+
srcStats.useless++;
|
|
93
|
+
}
|
|
94
|
+
srcStats.score = srcStats.total > 0 ? srcStats.useful / srcStats.total : 0;
|
|
95
|
+
this._sourceStats.set(srcKey, srcStats);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get stats for a specific item.
|
|
100
|
+
* @param {string} itemId
|
|
101
|
+
* @returns {ItemStats | undefined}
|
|
102
|
+
*/
|
|
103
|
+
getItemStats(itemId) {
|
|
104
|
+
return this._itemStats.get(itemId);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get stats for a specific source.
|
|
109
|
+
* @param {string} source
|
|
110
|
+
* @returns {SourceStats | undefined}
|
|
111
|
+
*/
|
|
112
|
+
getSourceStats(source) {
|
|
113
|
+
return this._sourceStats.get(source);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Get all recorded events.
|
|
118
|
+
* @returns {RetrievalEvent[]}
|
|
119
|
+
*/
|
|
120
|
+
getEvents() {
|
|
121
|
+
return [...this._events];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get items that were rated useless more than threshold times.
|
|
126
|
+
* These should be deprioritized or excluded in future retrievals.
|
|
127
|
+
* @param {number} [minUseless=3] - Minimum useless count to flag
|
|
128
|
+
* @returns {string[]} Item IDs
|
|
129
|
+
*/
|
|
130
|
+
getUselessItems(minUseless = 3) {
|
|
131
|
+
const result = [];
|
|
132
|
+
for (const [id, stats] of this._itemStats) {
|
|
133
|
+
if (stats.useless >= minUseless) {
|
|
134
|
+
result.push(id);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get sources with a success rate below threshold.
|
|
142
|
+
* @param {number} [minScore=0.2] - Minimum useful ratio
|
|
143
|
+
* @returns {string[]} Source names
|
|
144
|
+
*/
|
|
145
|
+
getLowPerformSources(minScore = 0.2) {
|
|
146
|
+
const result = [];
|
|
147
|
+
for (const [name, stats] of this._sourceStats) {
|
|
148
|
+
if (stats.total >= 2 && stats.score < minScore) {
|
|
149
|
+
result.push(name);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Get overall effectiveness score across all retrievals.
|
|
157
|
+
* @returns {number} 0-1
|
|
158
|
+
*/
|
|
159
|
+
overallScore() {
|
|
160
|
+
if (this._events.length === 0) return 0;
|
|
161
|
+
const useful = this._events.filter((e) => e.useful).length;
|
|
162
|
+
return useful / this._events.length;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get the most useful items (score = 1.0), sorted by lastUsed desc.
|
|
167
|
+
* @param {number} [limit=10]
|
|
168
|
+
* @returns {string[]}
|
|
169
|
+
*/
|
|
170
|
+
getTopItems(limit = 10) {
|
|
171
|
+
const top = [];
|
|
172
|
+
for (const [id, stats] of this._itemStats) {
|
|
173
|
+
if (stats.score === 1.0) {
|
|
174
|
+
top.push({ id, lastUsed: stats.lastUsed });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
top.sort((a, b) => b.lastUsed - a.lastUsed);
|
|
178
|
+
return top.slice(0, limit).map((i) => i.id);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Clear all telemetry data.
|
|
183
|
+
*/
|
|
184
|
+
reset() {
|
|
185
|
+
this._events = [];
|
|
186
|
+
this._itemStats.clear();
|
|
187
|
+
this._sourceStats.clear();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get summary statistics for the feedback loop.
|
|
192
|
+
* @returns {Object}
|
|
193
|
+
*/
|
|
194
|
+
summary() {
|
|
195
|
+
return {
|
|
196
|
+
totalEvents: this._events.length,
|
|
197
|
+
overallScore: this.overallScore(),
|
|
198
|
+
uniqueItems: this._itemStats.size,
|
|
199
|
+
uniqueSources: this._sourceStats.size,
|
|
200
|
+
topSources: [...this._sourceStats.entries()]
|
|
201
|
+
.sort((a, b) => b[1].score - a[1].score)
|
|
202
|
+
.slice(0, 5)
|
|
203
|
+
.map(([name, stats]) => ({ name, score: stats.score, total: stats.total })),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Factory function for creating a feedback loop (convenience).
|
|
210
|
+
* @returns {FeedbackLoop}
|
|
211
|
+
*/
|
|
212
|
+
export function createFeedbackLoop() {
|
|
213
|
+
return new FeedbackLoop();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export { FeedbackLoop };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Freshness Engine.
|
|
3
|
+
* Handles staleness calculation, TTL-based expiration, and last-access tracking.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export function calculateStaleness(item, now = Date.now()) {
|
|
7
|
+
const lastAccess = item.lastAccess || item.timestamp || 0;
|
|
8
|
+
return now - lastAccess;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function isStale(item, ttl, now = Date.now()) {
|
|
12
|
+
if (!ttl) return false;
|
|
13
|
+
return calculateStaleness(item, now) > ttl;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function updateLastAccess(item, now = Date.now()) {
|
|
17
|
+
return {
|
|
18
|
+
...item,
|
|
19
|
+
lastAccess: now,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Graph Builder — canonical reconstruction from runtime state.
|
|
3
|
+
*
|
|
4
|
+
* Maps TaskState, RunState, and EvidenceLineage into a ContextGraph.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ContextGraph } from "./context-graph.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Builds a canonical ContextGraph from runtime state.
|
|
11
|
+
*
|
|
12
|
+
* @param {Object} taskState - Current task state
|
|
13
|
+
* @param {Object} runState - Current run state
|
|
14
|
+
* @param {Object} evidenceLineage - Evidence/verification state
|
|
15
|
+
* @returns {ContextGraph}
|
|
16
|
+
*/
|
|
17
|
+
export function buildContextGraph(taskState, runState, evidenceLineage) {
|
|
18
|
+
const g = new ContextGraph();
|
|
19
|
+
|
|
20
|
+
// 1. Task Node
|
|
21
|
+
const taskId = taskState?.taskId || null;
|
|
22
|
+
if (taskId) {
|
|
23
|
+
g.addNode({
|
|
24
|
+
id: taskId,
|
|
25
|
+
type: "task",
|
|
26
|
+
content: taskState?.contract?.objective || "Active task",
|
|
27
|
+
metadata: { provenance: "user_decided" },
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 2. Requirement Nodes
|
|
32
|
+
for (const req of taskState?.requirements || []) {
|
|
33
|
+
if (!req?.id) continue;
|
|
34
|
+
g.addNode({
|
|
35
|
+
id: req.id,
|
|
36
|
+
type: "requirement",
|
|
37
|
+
content: req.title || req.description || "",
|
|
38
|
+
metadata: { provenance: "user_decided" },
|
|
39
|
+
});
|
|
40
|
+
// Task requires requirement (only if task node exists)
|
|
41
|
+
if (taskId) {
|
|
42
|
+
g.addEdge({
|
|
43
|
+
from: taskId,
|
|
44
|
+
to: req.id,
|
|
45
|
+
type: "requires_completion",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 3. Evidence Lineage (mapped to canonical edges)
|
|
51
|
+
for (const ev of evidenceLineage || []) {
|
|
52
|
+
if (!ev?.id) continue;
|
|
53
|
+
g.addNode({
|
|
54
|
+
id: ev.id,
|
|
55
|
+
type: "evidence",
|
|
56
|
+
content: ev.content || "",
|
|
57
|
+
verified: ev.status === "valid",
|
|
58
|
+
metadata: { provenance: "run_execution" },
|
|
59
|
+
});
|
|
60
|
+
// Evidence supports requirement (only if requirement node exists)
|
|
61
|
+
if (ev.requirementId && g.hasNode(ev.requirementId)) {
|
|
62
|
+
g.addEdge({
|
|
63
|
+
from: ev.id,
|
|
64
|
+
to: ev.requirementId,
|
|
65
|
+
type: "supports",
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return g;
|
|
71
|
+
}
|