@openship/protocol 0.1.0 → 0.1.1
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/README.md +2 -0
- package/dist/package-meta.json +2 -2
- package/dist/skill/references/examples/valid/systems-layered.json +21 -0
- package/dist/skill/references/openship-systems.md +18 -1
- package/dist/skill/references/schemas/systems.schema.json +36 -1
- package/package.json +1 -1
- package/src/index.d.ts +2 -1
- package/src/index.js +10 -0
package/README.md
CHANGED
|
@@ -15,3 +15,5 @@ if (imported.snapshot.kind === "systems") validateSystems(imported.snapshot.docu
|
|
|
15
15
|
The package contains the exact canonical `skills/openship` schemas, examples, and references. See the repository root README for the generated-skill workflow.
|
|
16
16
|
|
|
17
17
|
Version 0.1.0 replaces legacy Systems with `systemsVersion: "2.0"`: `system.layers`, `system.refinements`, and optional `system.instances`. Sources and Changes retain their 1.0 formats. Consumers must migrate; `validateSystems` explicitly rejects the legacy graph. Each layer is independently renderable, while node IDs and shared context span the entire system.
|
|
18
|
+
|
|
19
|
+
Version 0.1.1 adds optional `system.domains` entries (`id`, `name`, `nodeIds`, optional `description`). Membership may overlap and span layers. Documents without domains remain valid; `openship: "1.0"` and `systemsVersion: "2.0"` do not change.
|
package/dist/package-meta.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"openship": "1.0",
|
|
3
3
|
"package": "@openship/protocol",
|
|
4
|
-
"packageVersion": "0.1.
|
|
4
|
+
"packageVersion": "0.1.1",
|
|
5
5
|
"source": "https://github.com/openshipdev/openship/tree/main/skills/openship",
|
|
6
|
-
"sourceCommit": "
|
|
6
|
+
"sourceCommit": "fad5993fea4e1a21d95ec76d5ec89621364822b8"
|
|
7
7
|
}
|
|
@@ -326,6 +326,27 @@
|
|
|
326
326
|
}
|
|
327
327
|
]
|
|
328
328
|
}
|
|
329
|
+
],
|
|
330
|
+
"domains": [
|
|
331
|
+
{
|
|
332
|
+
"id": "web",
|
|
333
|
+
"name": "Web app",
|
|
334
|
+
"nodeIds": [
|
|
335
|
+
"logical.web",
|
|
336
|
+
"p.web",
|
|
337
|
+
"provider.web"
|
|
338
|
+
]
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"id": "state",
|
|
342
|
+
"name": "State",
|
|
343
|
+
"nodeIds": [
|
|
344
|
+
"logical.data",
|
|
345
|
+
"technical.data",
|
|
346
|
+
"provider.data",
|
|
347
|
+
"p.web"
|
|
348
|
+
]
|
|
349
|
+
}
|
|
329
350
|
]
|
|
330
351
|
},
|
|
331
352
|
"systemsVersion": "2.0"
|
|
@@ -65,6 +65,23 @@ Layer-local edges have `id`, `type`, `fromNodeId`, `toNodeId`, and optional meta
|
|
|
65
65
|
|
|
66
66
|
Refinements have `id`, `fromNodeId`, and `toNodeId`. IDs MUST be unique within `system.refinements`. The source MUST belong to a later layer than the target. Thus the concrete source implements the more abstract target. Many-to-many mappings, skipped layers, and root mappings are allowed. Refinements neither imply containment nor copy configuration, documents, or runtime edges.
|
|
67
67
|
|
|
68
|
+
## Domains (optional)
|
|
69
|
+
|
|
70
|
+
`system.domains` MAY declare an ordered list of domains. A domain groups blocks independently of layers, containment, and refinement. Each requires a unique `id`, a nonempty `name`, and `nodeIds`; an optional nonempty `description` explains its scope. Domain IDs use the standard ID grammar. Member IDs MUST be unique within the domain and MUST reference existing nodes anywhere in the system.
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
"domains": [
|
|
74
|
+
{ "id": "web", "name": "Web app", "nodeIds": ["logical.web", "technical.web"] },
|
|
75
|
+
{ "id": "state", "name": "State", "nodeIds": ["technical.web", "technical.database"] }
|
|
76
|
+
]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
A node MAY belong to zero, one, or multiple domains. Empty domains and an empty domain list are valid. Membership is explicit and is not inherited through parents or refinements. Omitting domains preserves the existing Systems behavior.
|
|
80
|
+
|
|
81
|
+
Viewers SHOULD select all domains initially. When filtering, a node matches if it has no domain or belongs to any selected domain. Keep the layer root and ancestors needed to render matching nodes as structural boundaries; this does not make other children visible. Hide connections whose endpoints do not match. Domain filters are presentation controls, not access controls. Keep domain selections across layer changes.
|
|
82
|
+
|
|
83
|
+
Domains are an additive capability in package 0.1.1. The envelope remains `openship: "1.0"` and `systemsVersion: "2.0"`.
|
|
84
|
+
|
|
68
85
|
## Configuration
|
|
69
86
|
|
|
70
87
|
Nodes and instance bindings MAY contain a `configuration` array. Each entry requires a unique `name`, a nonempty `description`, and a boolean `required` flag. Optional `value` contains JSON data; its absence means unresolved, whereas an explicit null is a supplied value.
|
|
@@ -159,7 +176,7 @@ Artifact IDs are unique within the system.
|
|
|
159
176
|
1. Envelope, Systems version, and embedded Sources integrity.
|
|
160
177
|
2. Layer IDs, global node IDs, roots, containment, configuration and source selectors.
|
|
161
178
|
3. Layer-local edges and cycle checks.
|
|
162
|
-
4.
|
|
179
|
+
4. Domain declarations and member references; refinement endpoints and order.
|
|
163
180
|
5. Instance membership, bindings, configuration, state and secret scopes.
|
|
164
181
|
6. Shared document hashes, concerns, matrix/artifact references, prompts and supersession chains.
|
|
165
182
|
|
|
@@ -77,7 +77,13 @@
|
|
|
77
77
|
},
|
|
78
78
|
"nodes": false,
|
|
79
79
|
"edges": false,
|
|
80
|
-
"rootNodeId": false
|
|
80
|
+
"rootNodeId": false,
|
|
81
|
+
"domains": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"items": {
|
|
84
|
+
"$ref": "#/$defs/domain"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
81
87
|
},
|
|
82
88
|
"additionalProperties": true
|
|
83
89
|
},
|
|
@@ -577,6 +583,35 @@
|
|
|
577
583
|
}
|
|
578
584
|
},
|
|
579
585
|
"additionalProperties": true
|
|
586
|
+
},
|
|
587
|
+
"domain": {
|
|
588
|
+
"type": "object",
|
|
589
|
+
"required": [
|
|
590
|
+
"id",
|
|
591
|
+
"name",
|
|
592
|
+
"nodeIds"
|
|
593
|
+
],
|
|
594
|
+
"properties": {
|
|
595
|
+
"id": {
|
|
596
|
+
"$ref": "#/$defs/id"
|
|
597
|
+
},
|
|
598
|
+
"name": {
|
|
599
|
+
"type": "string",
|
|
600
|
+
"minLength": 1
|
|
601
|
+
},
|
|
602
|
+
"description": {
|
|
603
|
+
"type": "string",
|
|
604
|
+
"minLength": 1
|
|
605
|
+
},
|
|
606
|
+
"nodeIds": {
|
|
607
|
+
"type": "array",
|
|
608
|
+
"items": {
|
|
609
|
+
"$ref": "#/$defs/id"
|
|
610
|
+
},
|
|
611
|
+
"uniqueItems": true
|
|
612
|
+
}
|
|
613
|
+
},
|
|
614
|
+
"additionalProperties": true
|
|
580
615
|
}
|
|
581
616
|
},
|
|
582
617
|
"additionalProperties": true
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -21,7 +21,8 @@ export interface SystemsLayer { id: string; name: string; role: "logical" | "tec
|
|
|
21
21
|
export interface SystemsRefinement { id: string; fromNodeId: string; toNodeId: string; [key: string]: unknown }
|
|
22
22
|
export interface SystemsBinding { nodeId: string; resourceId?: string; configuration?: SystemsConfiguration[]; state?: { appliedMigration?: string; snapshot?: { ref: string; capturedAt: string; digest?: string } }; [key: string]: unknown }
|
|
23
23
|
export interface SystemsInstance { id: string; name: string; environment: string; layerId: string; bindings: SystemsBinding[]; [key: string]: unknown }
|
|
24
|
-
export interface
|
|
24
|
+
export interface SystemsDomain { id: string; name: string; description?: string; nodeIds: string[]; [key: string]: unknown }
|
|
25
|
+
export interface SystemsGraph { id: string; name: string; layers: SystemsLayer[]; refinements: SystemsRefinement[]; domains?: SystemsDomain[]; instances?: SystemsInstance[]; metadata?: Record<string, unknown>; context?: Record<string, unknown>; [key: string]: unknown }
|
|
25
26
|
export interface SystemsDocument { openship: "1.0"; capability: "systems"; systemsVersion: "2.0"; source: { manifest: SourcesManifest; bundle: SourcesBundle; [key: string]: unknown }; system: SystemsGraph; [key: string]: unknown }
|
|
26
27
|
export interface VerifiedSourceFile { metadata: SourceFileMetadata; bytes: Uint8Array }
|
|
27
28
|
export interface VerifiedSources { manifest: SourcesManifest; bundle: SourcesBundle; files: VerifiedSourceFile[]; decodedBytes: number }
|
package/src/index.js
CHANGED
|
@@ -326,6 +326,16 @@ export function validateSystems(value, options = {}) {
|
|
|
326
326
|
}
|
|
327
327
|
for (const type of ["Dataflow", "Dependency"]) assertAcyclic([...local.keys()], edges.filter((edge) => edge.type === type).map((edge) => [edge.fromNodeId, edge.toNodeId]), `${at}.edges[${type}]`);
|
|
328
328
|
}
|
|
329
|
+
const domains = array(system.domains === undefined ? [] : system.domains, "$.system.domains");
|
|
330
|
+
unique(domains.map((domain) => identifier(object(domain, "$.system.domains").id, "$.system.domains.id")), "$.system.domains");
|
|
331
|
+
for (const domain of domains) {
|
|
332
|
+
const at = `$.system.domains.${domain.id}`;
|
|
333
|
+
string(domain.name, `${at}.name`);
|
|
334
|
+
if (domain.description !== undefined) string(domain.description, `${at}.description`);
|
|
335
|
+
const members = array(domain.nodeIds, `${at}.nodeIds`);
|
|
336
|
+
unique(members, `${at}.nodeIds`);
|
|
337
|
+
for (const nodeId of members) if (!nodeById.has(nodeId)) fail(`${at}.nodeIds`, "must reference existing system nodes");
|
|
338
|
+
}
|
|
329
339
|
const refinements = array(system.refinements, "$.system.refinements");
|
|
330
340
|
unique(refinements.map((ref) => identifier(object(ref, "$.system.refinements").id, "$.system.refinements.id")), "$.system.refinements");
|
|
331
341
|
for (const ref of refinements) {
|