@sigloch/graph-api-core 5.4.0 → 5.5.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/dist/format-e-codec.d.ts +0 -2
- package/dist/format-e-codec.js +3 -11
- package/dist/graph-service.js +17 -4
- package/dist/kuzu/graph-cypher-engine.js +21 -1
- package/dist/se-descriptor.js +7 -1
- package/dist/types.d.ts +7 -14
- package/dist/types.js +7 -14
- package/package.json +1 -1
package/dist/format-e-codec.d.ts
CHANGED
|
@@ -3,8 +3,6 @@ export declare class FormatECodec {
|
|
|
3
3
|
private readonly ontology;
|
|
4
4
|
private readonly edgeArrowToType;
|
|
5
5
|
private readonly validNodeTypes;
|
|
6
|
-
/** Trace-legality patterns (CR-GC-247) — the SSOT the parser validates edges against. */
|
|
7
|
-
private readonly patterns;
|
|
8
6
|
constructor(ontology: OntologyDescriptor);
|
|
9
7
|
/** Extract a ```format-e block from LLM output. Returns null if not found. */
|
|
10
8
|
extractFromLlm(llmOutput: string): string | null;
|
package/dist/format-e-codec.js
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* every foreign convention fail silently instead of loudly.
|
|
9
9
|
*/
|
|
10
10
|
import { hydrateAttrValue, attributeTypeOf } from '@sigloch/contracts/se';
|
|
11
|
-
import { isValidTrace, tracePatternsOf } from './types.js';
|
|
12
11
|
// ---------------------------------------------------------------------------
|
|
13
12
|
// Regex patterns
|
|
14
13
|
// ---------------------------------------------------------------------------
|
|
@@ -27,8 +26,6 @@ export class FormatECodec {
|
|
|
27
26
|
ontology;
|
|
28
27
|
edgeArrowToType;
|
|
29
28
|
validNodeTypes;
|
|
30
|
-
/** Trace-legality patterns (CR-GC-247) — the SSOT the parser validates edges against. */
|
|
31
|
-
patterns;
|
|
32
29
|
constructor(ontology) {
|
|
33
30
|
this.ontology = ontology;
|
|
34
31
|
// Build arrow → edge type lookup
|
|
@@ -40,8 +37,6 @@ export class FormatECodec {
|
|
|
40
37
|
}
|
|
41
38
|
// Valid node type abbreviations
|
|
42
39
|
this.validNodeTypes = new Set(Object.keys(ontology.nodeTypes));
|
|
43
|
-
// Meta-model legality: descriptor.patterns (or derived from validPairs).
|
|
44
|
-
this.patterns = tracePatternsOf(ontology);
|
|
45
40
|
}
|
|
46
41
|
/** Extract a ```format-e block from LLM output. Returns null if not found. */
|
|
47
42
|
extractFromLlm(llmOutput) {
|
|
@@ -290,12 +285,9 @@ export class FormatECodec {
|
|
|
290
285
|
errors.push(`Cannot resolve type of target "${targetId}" — not declared under a "### <TYPE>" section and no resolveType provided`);
|
|
291
286
|
continue;
|
|
292
287
|
}
|
|
293
|
-
//
|
|
294
|
-
//
|
|
295
|
-
|
|
296
|
-
errors.push(`Meta-model violation: ${srcType} -${edgeType}-> ${tgtType} is not valid`);
|
|
297
|
-
continue;
|
|
298
|
-
}
|
|
288
|
+
// CR-SM-324: no legality verdict while parsing — the parser knows neither label nor
|
|
289
|
+
// the kinds of existing nodes. The write path judges with the one rule (gate R-18,
|
|
290
|
+
// GraphService.validateAndApplyEdge).
|
|
299
291
|
const opType = action === 'remove'
|
|
300
292
|
? 'remove_edge'
|
|
301
293
|
: action === 'strict_add'
|
package/dist/graph-service.js
CHANGED
|
@@ -199,6 +199,7 @@ export class GraphService {
|
|
|
199
199
|
sourceId: op.sourceId,
|
|
200
200
|
targetId: op.targetId,
|
|
201
201
|
edgeType: op.edgeType,
|
|
202
|
+
label: op.attributes?.label,
|
|
202
203
|
});
|
|
203
204
|
const edge = {
|
|
204
205
|
sourceId: op.sourceId,
|
|
@@ -249,6 +250,7 @@ export class GraphService {
|
|
|
249
250
|
sourceId: op.sourceId,
|
|
250
251
|
targetId: op.targetId,
|
|
251
252
|
edgeType: op.edgeType,
|
|
253
|
+
label: op.attributes?.label,
|
|
252
254
|
});
|
|
253
255
|
const edge = {
|
|
254
256
|
sourceId: op.sourceId,
|
|
@@ -299,6 +301,7 @@ export class GraphService {
|
|
|
299
301
|
const { removed, added } = updateEdge(graph, { sourceId: op.sourceId, targetId: op.targetId, edgeType: op.edgeType }, op.set);
|
|
300
302
|
await this.validateAndApplyEdge({
|
|
301
303
|
sourceId: added.sourceId, targetId: added.targetId, edgeType: added.edgeType,
|
|
304
|
+
label: added.attributes?.label,
|
|
302
305
|
});
|
|
303
306
|
await this.storage.deleteEdges([{
|
|
304
307
|
sourceId: removed.sourceId, targetId: removed.targetId, edgeType: removed.edgeType,
|
|
@@ -337,6 +340,7 @@ export class GraphService {
|
|
|
337
340
|
for (const edge of addedEdges) {
|
|
338
341
|
await this.validateAndApplyEdge({
|
|
339
342
|
sourceId: edge.sourceId, targetId: edge.targetId, edgeType: edge.edgeType,
|
|
343
|
+
label: edge.attributes?.label,
|
|
340
344
|
});
|
|
341
345
|
}
|
|
342
346
|
if (removedEdges.length > 0) {
|
|
@@ -565,9 +569,11 @@ export class GraphService {
|
|
|
565
569
|
};
|
|
566
570
|
}
|
|
567
571
|
// CR-GC-247: one legality path for every ontology (SE + foreign). The edge type
|
|
568
|
-
// must be declared (menu enumeration via edgeTypes), then the
|
|
569
|
-
//
|
|
570
|
-
//
|
|
572
|
+
// must be declared (menu enumeration via edgeTypes), then the trace is checked against
|
|
573
|
+
// descriptor.patterns. CR-SM-323: that checker delegates to contracts' isValidTrace — the
|
|
574
|
+
// routine R-18 runs — fed label and endpoint kinds exactly as R-18 reads them. A foreign
|
|
575
|
+
// ontology's patterns (derived from validPairs) carry neither label nor where, so there
|
|
576
|
+
// the type pair alone decides.
|
|
571
577
|
async validateAndApplyEdge(op) {
|
|
572
578
|
if (!this.ontology.edgeTypes[op.edgeType]) {
|
|
573
579
|
const known = Object.keys(this.ontology.edgeTypes).join(', ');
|
|
@@ -575,7 +581,14 @@ export class GraphService {
|
|
|
575
581
|
}
|
|
576
582
|
const src = await this.storage.getNode(op.sourceId);
|
|
577
583
|
const tgt = await this.storage.getNode(op.targetId);
|
|
578
|
-
if (src && tgt && !isValidTrace({
|
|
584
|
+
if (src && tgt && !isValidTrace({
|
|
585
|
+
source: src.type,
|
|
586
|
+
target: tgt.type,
|
|
587
|
+
type: op.edgeType,
|
|
588
|
+
label: op.label,
|
|
589
|
+
sourceKinds: src.attributes?.kinds,
|
|
590
|
+
targetKinds: tgt.attributes?.kinds,
|
|
591
|
+
}, this.patterns)) {
|
|
579
592
|
const allowed = this.patterns
|
|
580
593
|
.filter(p => p.type === op.edgeType)
|
|
581
594
|
.map(p => `${p.source}->${p.target}`)
|
|
@@ -12,7 +12,27 @@
|
|
|
12
12
|
* Cypher) does not break consumers.
|
|
13
13
|
*/
|
|
14
14
|
import { generateSchema } from './schema-generator.js';
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Prozessweit genau EINE kuzu-Instanz (CR-SM-316).
|
|
17
|
+
*
|
|
18
|
+
* `kuzu.init()` ist nicht idempotent: jeder Aufruf legt eine NEUE Emscripten-Instanz
|
|
19
|
+
* mit eigenem Heap an (~186 MB) und haengt die alte ab. Zurueck gibt die niemand —
|
|
20
|
+
* WASM-Speicher schrumpft nicht, und weder `db.close()` noch der GC raeumen ihn ab.
|
|
21
|
+
* Vorher rief jedes `GraphCypherEngine.init()` erneut auf; im graphcode-Volllauf waren
|
|
22
|
+
* das 544 Aufrufe und 9641 MB Spitzenverbrauch, bis der Heap mit "memory access out of
|
|
23
|
+
* bounds" faultete und dabei traf, was gerade lief — in drei Laeufen drei verschiedene
|
|
24
|
+
* Testdateien.
|
|
25
|
+
*
|
|
26
|
+
* Der Cache haelt das PROMISE, nicht das Ergebnis: zwei Engines, die gleichzeitig
|
|
27
|
+
* initialisieren, warten damit auf denselben Ladevorgang statt zwei zu starten.
|
|
28
|
+
*/
|
|
29
|
+
let kuzuModule = null;
|
|
30
|
+
function loadKuzu() {
|
|
31
|
+
if (!kuzuModule)
|
|
32
|
+
kuzuModule = initKuzu();
|
|
33
|
+
return kuzuModule;
|
|
34
|
+
}
|
|
35
|
+
async function initKuzu() {
|
|
16
36
|
// Node path: sync nodejs variant. Detect Node by checking for `process.versions.node`.
|
|
17
37
|
const isNode = typeof process !== 'undefined' && !!process.versions?.node;
|
|
18
38
|
if (isNode) {
|
package/dist/se-descriptor.js
CHANGED
|
@@ -133,8 +133,14 @@ function liftAttributes(rest) {
|
|
|
133
133
|
* otherwise the 114 pre-existing errors in graphcode's own graph would block every
|
|
134
134
|
* write on debt the writer did not create. Promotion is a per-family decision, not a
|
|
135
135
|
* side effect of being registered.
|
|
136
|
+
*
|
|
137
|
+
* CR-SM-309: IO is promoted (decision 2026-09-11). IO-02 ("a FLOW has exactly ONE
|
|
138
|
+
* producer", error) guards the one-FLOW-per-connection cut; without gate power a
|
|
139
|
+
* suggested merge put two producers back into one FLOW and passed the gate. The delta
|
|
140
|
+
* baseline keeps the switch-on safe: only NEW findings block, graphcode's own graph is
|
|
141
|
+
* at IO-02 = 0, and IO-01 shares the prefix but is a warning, which never blocks.
|
|
136
142
|
*/
|
|
137
|
-
const GATING_PREFIXES = ['R-', 'RD-', 'MT-'];
|
|
143
|
+
const GATING_PREFIXES = ['R-', 'RD-', 'MT-', 'IO-'];
|
|
138
144
|
const SE_RULE_DEFS = [
|
|
139
145
|
...V3_RULES,
|
|
140
146
|
...UC_RULES,
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core types for graph-api-core — ontology-agnostic.
|
|
3
|
-
* Domains register their node/edge types via OntologyDescriptor.
|
|
4
|
-
*/
|
|
5
1
|
export interface GraphNode {
|
|
6
2
|
uid: string;
|
|
7
3
|
type: string;
|
|
@@ -135,21 +131,18 @@ export interface FormatEDiff {
|
|
|
135
131
|
errors: string[];
|
|
136
132
|
}
|
|
137
133
|
/**
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* A pattern's `label` is descriptive metadata (e.g. MS→MS relation 'depends-on'),
|
|
144
|
-
* NOT a gate: label is trace data that isn't uniformly carried through the
|
|
145
|
-
* Graph/codec pipeline, and the legality this replaces (validPairs) never keyed on
|
|
146
|
-
* it. Enforcing label is a deliberate tightening (needs codec label round-tripping),
|
|
147
|
-
* out of scope for the centralization.
|
|
134
|
+
* Trace legality for any ontology, decided by contracts' `isValidTrace` — the routine R-18
|
|
135
|
+
* runs. No logic of its own: `label` and endpoint `kinds` are part of the rule exactly as
|
|
136
|
+
* R-18 reads them. This signature only opens the SE-closed contracts types to the
|
|
137
|
+
* ontology-agnostic strings this package speaks; the runtime pattern shape is the same.
|
|
148
138
|
*/
|
|
149
139
|
export declare function isValidTrace(trace: {
|
|
150
140
|
source: string;
|
|
151
141
|
target: string;
|
|
152
142
|
type: string;
|
|
143
|
+
label?: string;
|
|
144
|
+
sourceKinds?: readonly string[];
|
|
145
|
+
targetKinds?: readonly string[];
|
|
153
146
|
}, patterns: TracePattern[]): boolean;
|
|
154
147
|
/**
|
|
155
148
|
* The patterns a descriptor validates against: explicit `patterns` (SSOT) if set,
|
package/dist/types.js
CHANGED
|
@@ -2,25 +2,18 @@
|
|
|
2
2
|
* Core types for graph-api-core — ontology-agnostic.
|
|
3
3
|
* Domains register their node/edge types via OntologyDescriptor.
|
|
4
4
|
*/
|
|
5
|
+
import { isValidTrace as contractsIsValidTrace } from '@sigloch/contracts/se';
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
|
-
// Trace legality —
|
|
7
|
+
// Trace legality — ONE rule (CR-GC-247, CR-SM-323)
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
8
9
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* A pattern's `label` is descriptive metadata (e.g. MS→MS relation 'depends-on'),
|
|
15
|
-
* NOT a gate: label is trace data that isn't uniformly carried through the
|
|
16
|
-
* Graph/codec pipeline, and the legality this replaces (validPairs) never keyed on
|
|
17
|
-
* it. Enforcing label is a deliberate tightening (needs codec label round-tripping),
|
|
18
|
-
* out of scope for the centralization.
|
|
10
|
+
* Trace legality for any ontology, decided by contracts' `isValidTrace` — the routine R-18
|
|
11
|
+
* runs. No logic of its own: `label` and endpoint `kinds` are part of the rule exactly as
|
|
12
|
+
* R-18 reads them. This signature only opens the SE-closed contracts types to the
|
|
13
|
+
* ontology-agnostic strings this package speaks; the runtime pattern shape is the same.
|
|
19
14
|
*/
|
|
20
15
|
export function isValidTrace(trace, patterns) {
|
|
21
|
-
return
|
|
22
|
-
(p.target === '*' || p.target === trace.target) &&
|
|
23
|
-
p.type === trace.type);
|
|
16
|
+
return contractsIsValidTrace(trace, patterns);
|
|
24
17
|
}
|
|
25
18
|
/**
|
|
26
19
|
* The patterns a descriptor validates against: explicit `patterns` (SSOT) if set,
|