@sigloch/contracts 0.7.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/LICENSE +21 -0
- package/dist/harness/index.d.ts +185 -0
- package/dist/harness/index.js +185 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +14 -0
- package/dist/se/ao-rules.d.ts +59 -0
- package/dist/se/ao-rules.js +341 -0
- package/dist/se/conformance-rules.d.ts +64 -0
- package/dist/se/conformance-rules.js +364 -0
- package/dist/se/cr-quality-rules.d.ts +8 -0
- package/dist/se/cr-quality-rules.js +141 -0
- package/dist/se/evaluate-all.d.ts +17 -0
- package/dist/se/evaluate-all.js +50 -0
- package/dist/se/fchain-quality-rules.d.ts +10 -0
- package/dist/se/fchain-quality-rules.js +105 -0
- package/dist/se/fmea-rules.d.ts +17 -0
- package/dist/se/fmea-rules.js +137 -0
- package/dist/se/format-e-parser.d.ts +28 -0
- package/dist/se/format-e-parser.js +217 -0
- package/dist/se/index.d.ts +28 -0
- package/dist/se/index.js +28 -0
- package/dist/se/meta-model.d.ts +26 -0
- package/dist/se/meta-model.js +60 -0
- package/dist/se/metric-rules.d.ts +45 -0
- package/dist/se/metric-rules.js +208 -0
- package/dist/se/near-duplicate-rules.d.ts +44 -0
- package/dist/se/near-duplicate-rules.js +106 -0
- package/dist/se/ontology.d.ts +327 -0
- package/dist/se/ontology.js +216 -0
- package/dist/se/quality-rules.d.ts +28 -0
- package/dist/se/quality-rules.js +206 -0
- package/dist/se/readiness.d.ts +62 -0
- package/dist/se/readiness.js +79 -0
- package/dist/se/rules.d.ts +159 -0
- package/dist/se/rules.js +854 -0
- package/dist/se/schema-quality-rules.d.ts +11 -0
- package/dist/se/schema-quality-rules.js +73 -0
- package/dist/se/semantic-id.d.ts +30 -0
- package/dist/se/semantic-id.js +90 -0
- package/dist/se/uc-quality-rules.d.ts +13 -0
- package/dist/se/uc-quality-rules.js +123 -0
- package/dist/se/view-rules.d.ts +11 -0
- package/dist/se/view-rules.js +56 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sigloch Consulting
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sigloch/contracts/harness — Graph-Harness interface contracts (D1).
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for the graphcode Apply-Gate surface:
|
|
5
|
+
* HarnessConfig · MutateCommand · MutateResult.
|
|
6
|
+
* Reconciled to the graph-api-core `Graph` model (uid/type/name on nodes,
|
|
7
|
+
* sourceId/targetId/edgeType on edges) — NOT the contracts/se OntologyGraph
|
|
8
|
+
* shape. Owned here (D1) so harness/MCP/hooks share one Zod schema instead of
|
|
9
|
+
* each redefining it locally (no parallel paths).
|
|
10
|
+
*
|
|
11
|
+
* @author andreas@siglochconsulting
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod/v4';
|
|
14
|
+
export declare const HarnessConfigSchema: z.ZodObject<{
|
|
15
|
+
repoRoot: z.ZodString;
|
|
16
|
+
scope: z.ZodObject<{
|
|
17
|
+
workspaceId: z.ZodString;
|
|
18
|
+
systemId: z.ZodString;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
consumerType: z.ZodDefault<z.ZodEnum<{
|
|
21
|
+
human: "human";
|
|
22
|
+
agent: "agent";
|
|
23
|
+
system: "system";
|
|
24
|
+
}>>;
|
|
25
|
+
preCommitTimeout: z.ZodDefault<z.ZodNumber>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
export type HarnessConfig = z.infer<typeof HarnessConfigSchema>;
|
|
28
|
+
export declare const MutateCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
29
|
+
op: z.ZodLiteral<"add-node">;
|
|
30
|
+
node: z.ZodObject<{
|
|
31
|
+
uid: z.ZodString;
|
|
32
|
+
type: z.ZodString;
|
|
33
|
+
name: z.ZodString;
|
|
34
|
+
description: z.ZodOptional<z.ZodString>;
|
|
35
|
+
attributes: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
38
|
+
op: z.ZodLiteral<"update-node">;
|
|
39
|
+
node: z.ZodObject<{
|
|
40
|
+
uid: z.ZodString;
|
|
41
|
+
type: z.ZodOptional<z.ZodString>;
|
|
42
|
+
name: z.ZodOptional<z.ZodString>;
|
|
43
|
+
description: z.ZodOptional<z.ZodString>;
|
|
44
|
+
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
45
|
+
}, z.core.$strip>;
|
|
46
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
47
|
+
op: z.ZodLiteral<"delete-node">;
|
|
48
|
+
uid: z.ZodString;
|
|
49
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
50
|
+
op: z.ZodLiteral<"add-edge">;
|
|
51
|
+
edge: z.ZodObject<{
|
|
52
|
+
sourceId: z.ZodString;
|
|
53
|
+
targetId: z.ZodString;
|
|
54
|
+
edgeType: z.ZodString;
|
|
55
|
+
attributes: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
56
|
+
}, z.core.$strip>;
|
|
57
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
58
|
+
op: z.ZodLiteral<"delete-edge">;
|
|
59
|
+
edge: z.ZodObject<{
|
|
60
|
+
sourceId: z.ZodString;
|
|
61
|
+
targetId: z.ZodString;
|
|
62
|
+
edgeType: z.ZodString;
|
|
63
|
+
}, z.core.$strip>;
|
|
64
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
65
|
+
op: z.ZodLiteral<"update-edge">;
|
|
66
|
+
edge: z.ZodObject<{
|
|
67
|
+
sourceId: z.ZodString;
|
|
68
|
+
targetId: z.ZodString;
|
|
69
|
+
edgeType: z.ZodString;
|
|
70
|
+
}, z.core.$strip>;
|
|
71
|
+
set: z.ZodObject<{
|
|
72
|
+
edgeType: z.ZodOptional<z.ZodString>;
|
|
73
|
+
flip: z.ZodOptional<z.ZodBoolean>;
|
|
74
|
+
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
75
|
+
}, z.core.$strip>;
|
|
76
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
77
|
+
op: z.ZodLiteral<"merge-nodes">;
|
|
78
|
+
sourceUid: z.ZodString;
|
|
79
|
+
targetUid: z.ZodString;
|
|
80
|
+
}, z.core.$strip>], "op">;
|
|
81
|
+
export type MutateCommand = z.infer<typeof MutateCommandSchema>;
|
|
82
|
+
/** Monotone graph revision; incremented by +1 per successful mutate(). */
|
|
83
|
+
export declare const GraphVersionSchema: z.ZodNumber;
|
|
84
|
+
export type GraphVersion = z.infer<typeof GraphVersionSchema>;
|
|
85
|
+
/** Optional second arg to harness.mutate(commands, options?). */
|
|
86
|
+
export declare const MutateOptionsSchema: z.ZodObject<{
|
|
87
|
+
baseVersion: z.ZodOptional<z.ZodNumber>;
|
|
88
|
+
}, z.core.$strip>;
|
|
89
|
+
export type MutateOptions = z.infer<typeof MutateOptionsSchema>;
|
|
90
|
+
/** One applied batch between `sinceVersion` and `currentVersion`. */
|
|
91
|
+
export declare const StaleDeltaEntrySchema: z.ZodObject<{
|
|
92
|
+
graphVersion: z.ZodNumber;
|
|
93
|
+
ts: z.ZodString;
|
|
94
|
+
changedUids: z.ZodArray<z.ZodString>;
|
|
95
|
+
}, z.core.$strip>;
|
|
96
|
+
export type StaleDeltaEntry = z.infer<typeof StaleDeltaEntrySchema>;
|
|
97
|
+
export declare const StaleDeltaSchema: z.ZodObject<{
|
|
98
|
+
sinceVersion: z.ZodNumber;
|
|
99
|
+
currentVersion: z.ZodNumber;
|
|
100
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
101
|
+
graphVersion: z.ZodNumber;
|
|
102
|
+
ts: z.ZodString;
|
|
103
|
+
changedUids: z.ZodArray<z.ZodString>;
|
|
104
|
+
}, z.core.$strip>>;
|
|
105
|
+
changedUids: z.ZodArray<z.ZodString>;
|
|
106
|
+
}, z.core.$strip>;
|
|
107
|
+
export type StaleDelta = z.infer<typeof StaleDeltaSchema>;
|
|
108
|
+
export declare const RuleViolationSchema: z.ZodObject<{
|
|
109
|
+
ruleId: z.ZodString;
|
|
110
|
+
severity: z.ZodEnum<{
|
|
111
|
+
error: "error";
|
|
112
|
+
warning: "warning";
|
|
113
|
+
info: "info";
|
|
114
|
+
}>;
|
|
115
|
+
message: z.ZodString;
|
|
116
|
+
elementId: z.ZodOptional<z.ZodString>;
|
|
117
|
+
fixHint: z.ZodOptional<z.ZodString>;
|
|
118
|
+
context: z.ZodOptional<z.ZodUnknown>;
|
|
119
|
+
}, z.core.$strip>;
|
|
120
|
+
export type RuleViolation = z.infer<typeof RuleViolationSchema>;
|
|
121
|
+
/** Apply tier derived from violation severity (3-tier gate, R1). */
|
|
122
|
+
export declare const MutateTier: z.ZodEnum<{
|
|
123
|
+
"auto-apply": "auto-apply";
|
|
124
|
+
suggest: "suggest";
|
|
125
|
+
block: "block";
|
|
126
|
+
}>;
|
|
127
|
+
export type MutateTier = z.infer<typeof MutateTier>;
|
|
128
|
+
export declare const MutateResultSchema: z.ZodObject<{
|
|
129
|
+
success: z.ZodBoolean;
|
|
130
|
+
appliedCommands: z.ZodNumber;
|
|
131
|
+
mutations: z.ZodNumber;
|
|
132
|
+
violations: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
133
|
+
ruleId: z.ZodString;
|
|
134
|
+
severity: z.ZodEnum<{
|
|
135
|
+
error: "error";
|
|
136
|
+
warning: "warning";
|
|
137
|
+
info: "info";
|
|
138
|
+
}>;
|
|
139
|
+
message: z.ZodString;
|
|
140
|
+
elementId: z.ZodOptional<z.ZodString>;
|
|
141
|
+
fixHint: z.ZodOptional<z.ZodString>;
|
|
142
|
+
context: z.ZodOptional<z.ZodUnknown>;
|
|
143
|
+
}, z.core.$strip>>>;
|
|
144
|
+
confidence: z.ZodOptional<z.ZodNumber>;
|
|
145
|
+
tier: z.ZodOptional<z.ZodEnum<{
|
|
146
|
+
"auto-apply": "auto-apply";
|
|
147
|
+
suggest: "suggest";
|
|
148
|
+
block: "block";
|
|
149
|
+
}>>;
|
|
150
|
+
trajectoryId: z.ZodOptional<z.ZodString>;
|
|
151
|
+
graphVersion: z.ZodOptional<z.ZodNumber>;
|
|
152
|
+
stale: z.ZodOptional<z.ZodBoolean>;
|
|
153
|
+
staleDelta: z.ZodOptional<z.ZodObject<{
|
|
154
|
+
sinceVersion: z.ZodNumber;
|
|
155
|
+
currentVersion: z.ZodNumber;
|
|
156
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
157
|
+
graphVersion: z.ZodNumber;
|
|
158
|
+
ts: z.ZodString;
|
|
159
|
+
changedUids: z.ZodArray<z.ZodString>;
|
|
160
|
+
}, z.core.$strip>>;
|
|
161
|
+
changedUids: z.ZodArray<z.ZodString>;
|
|
162
|
+
}, z.core.$strip>>;
|
|
163
|
+
}, z.core.$strip>;
|
|
164
|
+
export type MutateResult = z.infer<typeof MutateResultSchema>;
|
|
165
|
+
/** Domains a mutation may invalidate (superset; always at least ['graph']). */
|
|
166
|
+
export declare const UpdateDomainSchema: z.ZodEnum<{
|
|
167
|
+
graph: "graph";
|
|
168
|
+
rules: "rules";
|
|
169
|
+
readiness: "readiness";
|
|
170
|
+
suggestions: "suggestions";
|
|
171
|
+
}>;
|
|
172
|
+
export type UpdateDomain = z.infer<typeof UpdateDomainSchema>;
|
|
173
|
+
/** Emitted once per mutation; an SSE handler serialises it as an `invalidate` event. */
|
|
174
|
+
export declare const LiveUpdateEventSchema: z.ZodObject<{
|
|
175
|
+
type: z.ZodLiteral<"invalidate">;
|
|
176
|
+
domains: z.ZodArray<z.ZodEnum<{
|
|
177
|
+
graph: "graph";
|
|
178
|
+
rules: "rules";
|
|
179
|
+
readiness: "readiness";
|
|
180
|
+
suggestions: "suggestions";
|
|
181
|
+
}>>;
|
|
182
|
+
ts: z.ZodString;
|
|
183
|
+
version: z.ZodOptional<z.ZodNumber>;
|
|
184
|
+
}, z.core.$strip>;
|
|
185
|
+
export type LiveUpdateEvent = z.infer<typeof LiveUpdateEventSchema>;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sigloch/contracts/harness — Graph-Harness interface contracts (D1).
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for the graphcode Apply-Gate surface:
|
|
5
|
+
* HarnessConfig · MutateCommand · MutateResult.
|
|
6
|
+
* Reconciled to the graph-api-core `Graph` model (uid/type/name on nodes,
|
|
7
|
+
* sourceId/targetId/edgeType on edges) — NOT the contracts/se OntologyGraph
|
|
8
|
+
* shape. Owned here (D1) so harness/MCP/hooks share one Zod schema instead of
|
|
9
|
+
* each redefining it locally (no parallel paths).
|
|
10
|
+
*
|
|
11
|
+
* @author andreas@siglochconsulting
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod/v4';
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// HarnessConfig — one harness instance per repo (single Kuzu owner).
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
export const HarnessConfigSchema = z.object({
|
|
18
|
+
/** Repo root; the Kuzu store lives at `<repoRoot>/.graphcode/kuzu`. */
|
|
19
|
+
repoRoot: z.string(),
|
|
20
|
+
/** Graph scope this harness owns. */
|
|
21
|
+
scope: z.object({
|
|
22
|
+
workspaceId: z.string(),
|
|
23
|
+
systemId: z.string(),
|
|
24
|
+
}),
|
|
25
|
+
/** Who is driving the harness; logged on mutations, never used to skip the gate (L1). */
|
|
26
|
+
consumerType: z.enum(['human', 'agent', 'system']).default('agent'),
|
|
27
|
+
/** Pre-commit hook timeout in ms. */
|
|
28
|
+
preCommitTimeout: z.number().int().positive().default(5000),
|
|
29
|
+
});
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// MutateCommand — discriminated union over the four graph mutations.
|
|
32
|
+
// Node payloads use uid/type/name; edge payloads use sourceId/targetId/edgeType.
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
const NodePayloadSchema = z.object({
|
|
35
|
+
uid: z.string(),
|
|
36
|
+
type: z.string(),
|
|
37
|
+
name: z.string(),
|
|
38
|
+
description: z.string().optional(),
|
|
39
|
+
attributes: z.record(z.string(), z.unknown()).default({}),
|
|
40
|
+
});
|
|
41
|
+
const NodePatchSchema = z.object({
|
|
42
|
+
uid: z.string(),
|
|
43
|
+
type: z.string().optional(),
|
|
44
|
+
name: z.string().optional(),
|
|
45
|
+
description: z.string().optional(),
|
|
46
|
+
attributes: z.record(z.string(), z.unknown()).optional(),
|
|
47
|
+
});
|
|
48
|
+
const EdgePayloadSchema = z.object({
|
|
49
|
+
sourceId: z.string(),
|
|
50
|
+
targetId: z.string(),
|
|
51
|
+
edgeType: z.string(),
|
|
52
|
+
attributes: z.record(z.string(), z.unknown()).default({}),
|
|
53
|
+
});
|
|
54
|
+
export const MutateCommandSchema = z.discriminatedUnion('op', [
|
|
55
|
+
z.object({ op: z.literal('add-node'), node: NodePayloadSchema }),
|
|
56
|
+
z.object({ op: z.literal('update-node'), node: NodePatchSchema }),
|
|
57
|
+
z.object({ op: z.literal('delete-node'), uid: z.string() }),
|
|
58
|
+
z.object({ op: z.literal('add-edge'), edge: EdgePayloadSchema }),
|
|
59
|
+
z.object({
|
|
60
|
+
op: z.literal('delete-edge'),
|
|
61
|
+
edge: z.object({
|
|
62
|
+
sourceId: z.string(),
|
|
63
|
+
targetId: z.string(),
|
|
64
|
+
edgeType: z.string(),
|
|
65
|
+
}),
|
|
66
|
+
}),
|
|
67
|
+
// CR-196: Typwechsel und/oder Richtungswechsel als EIN semantischer Op —
|
|
68
|
+
// im Audit unterscheidbar von delete+add (Flip ≠ Delete+Add).
|
|
69
|
+
z.object({
|
|
70
|
+
op: z.literal('update-edge'),
|
|
71
|
+
/** Identität der bestehenden Kante. */
|
|
72
|
+
edge: z.object({
|
|
73
|
+
sourceId: z.string(),
|
|
74
|
+
targetId: z.string(),
|
|
75
|
+
edgeType: z.string(),
|
|
76
|
+
}),
|
|
77
|
+
/** Änderung; mindestens ein Feld muss gesetzt sein. */
|
|
78
|
+
set: z
|
|
79
|
+
.object({
|
|
80
|
+
edgeType: z.string().optional(),
|
|
81
|
+
flip: z.boolean().optional(),
|
|
82
|
+
attributes: z.record(z.string(), z.unknown()).optional(),
|
|
83
|
+
})
|
|
84
|
+
.refine((s) => s.edgeType !== undefined || s.flip !== undefined || s.attributes !== undefined, {
|
|
85
|
+
message: 'update-edge.set requires at least one of edgeType|flip|attributes',
|
|
86
|
+
}),
|
|
87
|
+
}),
|
|
88
|
+
// CR-196: target absorbiert source — Kanten umgehängt, source gelöscht,
|
|
89
|
+
// Gate prüft den Ergebnisgraph (R-18); keine Client-komponierten Batches.
|
|
90
|
+
z.object({
|
|
91
|
+
op: z.literal('merge-nodes'),
|
|
92
|
+
sourceUid: z.string(),
|
|
93
|
+
targetUid: z.string(),
|
|
94
|
+
}),
|
|
95
|
+
]);
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// CR-199: OCC — graph revision + optional baseVersion on mutate().
|
|
98
|
+
// Schema-only here; revision counter/stale-check/delta live in the harness
|
|
99
|
+
// (graphcode follow-up CR). Additive: omitting baseVersion keeps today's
|
|
100
|
+
// last-write-wins behavior (no conflict check).
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
/** Monotone graph revision; incremented by +1 per successful mutate(). */
|
|
103
|
+
export const GraphVersionSchema = z.number().int().nonnegative();
|
|
104
|
+
/** Optional second arg to harness.mutate(commands, options?). */
|
|
105
|
+
export const MutateOptionsSchema = z.object({
|
|
106
|
+
baseVersion: GraphVersionSchema.optional(),
|
|
107
|
+
});
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// CR-200: staleDelta aligned with graphcode CR-GC-233's proven shape — the
|
|
110
|
+
// applied batches since `sinceVersion`, not just a flattened UID projection.
|
|
111
|
+
// `changedUids` stays as the union convenience field (CR-199).
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
/** One applied batch between `sinceVersion` and `currentVersion`. */
|
|
114
|
+
export const StaleDeltaEntrySchema = z.object({
|
|
115
|
+
/** Graph revision produced by this batch. */
|
|
116
|
+
graphVersion: GraphVersionSchema,
|
|
117
|
+
/** ISO timestamp the batch was applied. */
|
|
118
|
+
ts: z.string(),
|
|
119
|
+
/** Elements this batch touched. */
|
|
120
|
+
changedUids: z.array(z.string()),
|
|
121
|
+
});
|
|
122
|
+
export const StaleDeltaSchema = z.object({
|
|
123
|
+
sinceVersion: GraphVersionSchema,
|
|
124
|
+
currentVersion: GraphVersionSchema,
|
|
125
|
+
/** Applied batches since sinceVersion, in order. */
|
|
126
|
+
entries: z.array(StaleDeltaEntrySchema),
|
|
127
|
+
/** Union of entries[].changedUids — convenience for callers that only need invalidation targets. */
|
|
128
|
+
changedUids: z.array(z.string()),
|
|
129
|
+
});
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// MutateResult — outcome of the Apply-Gate, incl. 3-tier confidence (R1).
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
export const RuleViolationSchema = z.object({
|
|
134
|
+
ruleId: z.string(),
|
|
135
|
+
severity: z.enum(['error', 'warning', 'info']),
|
|
136
|
+
message: z.string(),
|
|
137
|
+
elementId: z.string().optional(),
|
|
138
|
+
/** CR-GC-203 item 1: how to fix this violation (carried from the contracts rule). */
|
|
139
|
+
fixHint: z.string().optional(),
|
|
140
|
+
/** Fix-context (candidate_targets, existing_traces, …) so an agent resolves the
|
|
141
|
+
* violation from the payload — no extra DB queries. Validated upstream in se/rules.ts. */
|
|
142
|
+
context: z.unknown().optional(),
|
|
143
|
+
});
|
|
144
|
+
/** Apply tier derived from violation severity (3-tier gate, R1). */
|
|
145
|
+
export const MutateTier = z.enum(['auto-apply', 'suggest', 'block']);
|
|
146
|
+
export const MutateResultSchema = z.object({
|
|
147
|
+
/** false iff a pre-commit hook blocked or an error-severity rule fired. */
|
|
148
|
+
success: z.boolean(),
|
|
149
|
+
/** Number of commands applied in-memory before evaluation. */
|
|
150
|
+
appliedCommands: z.number().int().nonnegative(),
|
|
151
|
+
/** Net node/edge mutations persisted (0 when blocked). */
|
|
152
|
+
mutations: z.number().int().nonnegative(),
|
|
153
|
+
/** All rule violations from evaluateRules (empty when clean). */
|
|
154
|
+
violations: z.array(RuleViolationSchema).default([]),
|
|
155
|
+
/** Confidence 0..1; defaults to 1 for deterministic human/system edits. */
|
|
156
|
+
confidence: z.number().min(0).max(1).optional(),
|
|
157
|
+
/** Gate decision tier: block (error) | suggest (warning) | auto-apply (clean). */
|
|
158
|
+
tier: MutateTier.optional(),
|
|
159
|
+
/** Set by CR-102 when a trajectory is recorded; absent here. */
|
|
160
|
+
trajectoryId: z.string().optional(),
|
|
161
|
+
/** CR-199: graph revision after apply (success only). */
|
|
162
|
+
graphVersion: GraphVersionSchema.optional(),
|
|
163
|
+
/** CR-199: true iff baseVersion != current revision — nothing applied, no rule evaluation ran. */
|
|
164
|
+
stale: z.boolean().optional(),
|
|
165
|
+
/** CR-199/CR-200: present iff stale — the delta for client re-read + retry. */
|
|
166
|
+
staleDelta: StaleDeltaSchema.optional(),
|
|
167
|
+
});
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
// LiveUpdateEvent — the SSE invalidation contract (CR-GC-109).
|
|
170
|
+
// Defined ONCE here so the emitting harness AND the dashboard/host-bridge that
|
|
171
|
+
// consume the SSE stream share one Zod schema (no fork, analog D1). graphcode
|
|
172
|
+
// src/emit.ts re-exports these; the host serialises a LiveUpdateEvent per
|
|
173
|
+
// mutation, the viewer parses it with LiveUpdateEventSchema.
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
/** Domains a mutation may invalidate (superset; always at least ['graph']). */
|
|
176
|
+
export const UpdateDomainSchema = z.enum(['graph', 'rules', 'readiness', 'suggestions']);
|
|
177
|
+
/** Emitted once per mutation; an SSE handler serialises it as an `invalidate` event. */
|
|
178
|
+
export const LiveUpdateEventSchema = z.object({
|
|
179
|
+
type: z.literal('invalidate'),
|
|
180
|
+
domains: z.array(UpdateDomainSchema),
|
|
181
|
+
/** ISO timestamp of when the event was produced. */
|
|
182
|
+
ts: z.string(),
|
|
183
|
+
/** CR-199: graph revision after the mutation that triggered this event. */
|
|
184
|
+
version: GraphVersionSchema.optional(),
|
|
185
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sigloch/contracts
|
|
3
|
+
* Zod-based contracts as single source of truth for the SE model layer.
|
|
4
|
+
*
|
|
5
|
+
* Scope is `se` (ontology + rules) plus the `harness` schemas on the `./harness`
|
|
6
|
+
* subpath. Domain ontologies live in their product repo, not here (CR-205): the
|
|
7
|
+
* finance ontology moved to moneyflow, and the empty `immo`/`content` subtrees —
|
|
8
|
+
* with their exports pointing at files that were never built — are gone.
|
|
9
|
+
*
|
|
10
|
+
* @author andreas@siglochconsulting
|
|
11
|
+
*/
|
|
12
|
+
export * as se from './se/index.js';
|
|
13
|
+
export { z } from 'zod/v4';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sigloch/contracts
|
|
3
|
+
* Zod-based contracts as single source of truth for the SE model layer.
|
|
4
|
+
*
|
|
5
|
+
* Scope is `se` (ontology + rules) plus the `harness` schemas on the `./harness`
|
|
6
|
+
* subpath. Domain ontologies live in their product repo, not here (CR-205): the
|
|
7
|
+
* finance ontology moved to moneyflow, and the empty `immo`/`content` subtrees —
|
|
8
|
+
* with their exports pointing at files that were never built — are gone.
|
|
9
|
+
*
|
|
10
|
+
* @author andreas@siglochconsulting
|
|
11
|
+
*/
|
|
12
|
+
// Domain exports
|
|
13
|
+
export * as se from './se/index.js';
|
|
14
|
+
export { z } from 'zod/v4';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CR-159: AO-D Architecture Optimization Detection Rules.
|
|
3
|
+
* Severity: info (optimization hints [OH], not blocking violations).
|
|
4
|
+
*/
|
|
5
|
+
import type { OntologyGraph } from './ontology.js';
|
|
6
|
+
import type { RuleViolation } from './rules.js';
|
|
7
|
+
/**
|
|
8
|
+
* AO-D01: Relay Node Detection.
|
|
9
|
+
* A FUNC is a relay if it (a) satisfies no REQ, (b) has >=2 outgoing io to FUNCs,
|
|
10
|
+
* and (c) target FUNCs share SCHEMA overlap >= 0.5 (via ND-02 matrix, skipped if unavailable).
|
|
11
|
+
*/
|
|
12
|
+
export declare function aoD01RelayNode(graph: OntologyGraph): RuleViolation[];
|
|
13
|
+
/**
|
|
14
|
+
* AO-D03: Duplicate Path Detection.
|
|
15
|
+
* FUNC A sends io to both B and C, where B and C connect to the same SCHEMA elements.
|
|
16
|
+
*/
|
|
17
|
+
export declare function aoD03DuplicatePath(graph: OntologyGraph): RuleViolation[];
|
|
18
|
+
export declare function cr01CrossingFlowCount(graph: OntologyGraph): RuleViolation[];
|
|
19
|
+
export declare function rt01PhysicalBoundaryIntegrity(graph: OntologyGraph): RuleViolation[];
|
|
20
|
+
export declare function ph01PhysicalModCompleteness(graph: OntologyGraph): RuleViolation[];
|
|
21
|
+
export declare function ca01CapabilityAllocation(graph: OntologyGraph): RuleViolation[];
|
|
22
|
+
export declare function io01CrossModuleCompleteness(graph: OntologyGraph): RuleViolation[];
|
|
23
|
+
export declare const AO_RULES: readonly [{
|
|
24
|
+
readonly id: "AO-D01";
|
|
25
|
+
readonly name: "RelayNodeDetection";
|
|
26
|
+
readonly severity: "info";
|
|
27
|
+
readonly evaluate: typeof aoD01RelayNode;
|
|
28
|
+
}, {
|
|
29
|
+
readonly id: "AO-D03";
|
|
30
|
+
readonly name: "DuplicatePathDetection";
|
|
31
|
+
readonly severity: "info";
|
|
32
|
+
readonly evaluate: typeof aoD03DuplicatePath;
|
|
33
|
+
}, {
|
|
34
|
+
readonly id: "CR-01";
|
|
35
|
+
readonly name: "CrossingFlowCount";
|
|
36
|
+
readonly severity: "warning";
|
|
37
|
+
readonly evaluate: typeof cr01CrossingFlowCount;
|
|
38
|
+
}, {
|
|
39
|
+
readonly id: "RT-01";
|
|
40
|
+
readonly name: "PhysicalBoundaryIntegrity";
|
|
41
|
+
readonly severity: "error";
|
|
42
|
+
readonly evaluate: typeof rt01PhysicalBoundaryIntegrity;
|
|
43
|
+
}, {
|
|
44
|
+
readonly id: "PH-01";
|
|
45
|
+
readonly name: "PhysicalModCompleteness";
|
|
46
|
+
readonly severity: "info";
|
|
47
|
+
readonly evaluate: typeof ph01PhysicalModCompleteness;
|
|
48
|
+
}, {
|
|
49
|
+
readonly id: "CA-01";
|
|
50
|
+
readonly name: "CapabilityAllocation";
|
|
51
|
+
readonly severity: "error";
|
|
52
|
+
readonly evaluate: typeof ca01CapabilityAllocation;
|
|
53
|
+
}, {
|
|
54
|
+
readonly id: "IO-01";
|
|
55
|
+
readonly name: "CrossModuleIOCompleteness";
|
|
56
|
+
readonly severity: "warning";
|
|
57
|
+
readonly evaluate: typeof io01CrossModuleCompleteness;
|
|
58
|
+
}];
|
|
59
|
+
export declare function evaluateAORules(graph: OntologyGraph): RuleViolation[];
|