@openship/protocol 0.0.3 → 0.1.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/README.md +2 -0
- package/dist/package-meta.json +2 -2
- package/dist/skill/SKILL.md +1 -1
- package/dist/skill/references/examples/invalid/systems-ownership.json +29 -7
- package/dist/skill/references/examples/invalid/systems.json +63 -12
- package/dist/skill/references/examples/valid/systems-layered.json +332 -0
- package/dist/skill/references/examples/valid/systems.json +140 -25
- package/dist/skill/references/openship-systems.md +70 -69
- package/dist/skill/references/openship.md +1 -1
- package/dist/skill/references/schemas/systems.schema.json +519 -57
- package/package.json +1 -1
- package/src/index.d.ts +11 -4
- package/src/index.js +120 -39
|
@@ -6,11 +6,31 @@
|
|
|
6
6
|
"openship": "1.0",
|
|
7
7
|
"capability": "sources",
|
|
8
8
|
"digest": "sha256:1d322539e651a3c2d7c51eb8b33160627395b9601bff909e599771b806d9e565",
|
|
9
|
-
"project": {
|
|
10
|
-
|
|
9
|
+
"project": {
|
|
10
|
+
"name": "Example",
|
|
11
|
+
"description": "An example OpenShip project."
|
|
12
|
+
},
|
|
13
|
+
"totals": {
|
|
14
|
+
"files": 2,
|
|
15
|
+
"bytes": 53
|
|
16
|
+
},
|
|
11
17
|
"files": [
|
|
12
|
-
{
|
|
13
|
-
|
|
18
|
+
{
|
|
19
|
+
"path": "app/page.js",
|
|
20
|
+
"size": 34,
|
|
21
|
+
"sha256": "6ce070542590adb63fd9621ff65be91446f8bd9b65465cda5e4ec43e5d86dc5e",
|
|
22
|
+
"encoding": "utf-8",
|
|
23
|
+
"mediaType": "text/plain; charset=utf-8",
|
|
24
|
+
"type": "file"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "package.json",
|
|
28
|
+
"size": 19,
|
|
29
|
+
"sha256": "9579cf52285b23b618b615d704b19d04ff591ae513f6ae34ef37e2b9a067cb12",
|
|
30
|
+
"encoding": "utf-8",
|
|
31
|
+
"mediaType": "application/json; charset=utf-8",
|
|
32
|
+
"type": "file"
|
|
33
|
+
}
|
|
14
34
|
]
|
|
15
35
|
},
|
|
16
36
|
"bundle": {
|
|
@@ -18,38 +38,133 @@
|
|
|
18
38
|
"capability": "sources",
|
|
19
39
|
"digest": "sha256:1d322539e651a3c2d7c51eb8b33160627395b9601bff909e599771b806d9e565",
|
|
20
40
|
"files": {
|
|
21
|
-
"app/page.js": {
|
|
22
|
-
|
|
41
|
+
"app/page.js": {
|
|
42
|
+
"encoding": "utf-8",
|
|
43
|
+
"content": "export default function Page() {}\n"
|
|
44
|
+
},
|
|
45
|
+
"package.json": {
|
|
46
|
+
"encoding": "utf-8",
|
|
47
|
+
"content": "{\"name\":\"example\"}\n"
|
|
48
|
+
}
|
|
23
49
|
}
|
|
24
50
|
}
|
|
25
51
|
},
|
|
26
52
|
"system": {
|
|
27
53
|
"id": "example-system",
|
|
28
54
|
"name": "Example system",
|
|
29
|
-
"rootNodeId": "s.root",
|
|
30
|
-
"nodes": [
|
|
31
|
-
{ "id": "s.root", "kind": "Root", "name": "Example", "metadata": { "ownership": "first_party" } },
|
|
32
|
-
{ "id": "h.runtime", "kind": "Host", "name": "Application runtime", "parentId": "s.root", "metadata": { "ownership": "first_party" } },
|
|
33
|
-
{ "id": "p.web", "kind": "Process", "name": "Web process", "parentId": "h.runtime", "sourceSelectors": ["app/**"], "metadata": { "ownership": "first_party" } },
|
|
34
|
-
{ "id": "l.config", "kind": "Library", "name": "Project configuration", "sourceSelectors": ["package.json"], "metadata": { "ownership": "third_party" } }
|
|
35
|
-
],
|
|
36
|
-
"edges": [
|
|
37
|
-
{ "id": "e.web.config", "type": "Dependency", "fromNodeId": "p.web", "toNodeId": "l.config" }
|
|
38
|
-
],
|
|
39
55
|
"context": {
|
|
40
|
-
"concerns": [
|
|
56
|
+
"concerns": [
|
|
57
|
+
"Interfaces",
|
|
58
|
+
"Implementation"
|
|
59
|
+
],
|
|
41
60
|
"documents": [
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
{
|
|
62
|
+
"kind": "Document",
|
|
63
|
+
"hash": "sha256:77760f8cb9fdaaadd3c22612d97fba630f78730c8d750c6cce02754b689b11da",
|
|
64
|
+
"title": "API contract",
|
|
65
|
+
"language": "en",
|
|
66
|
+
"text": "The API returns JSON."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"kind": "Skill",
|
|
70
|
+
"hash": "sha256:bae5f866c2994c1cec740965e45935920376a2df1fb933e798c3e2c3b8c0e391",
|
|
71
|
+
"title": "Node implementation",
|
|
72
|
+
"language": "en",
|
|
73
|
+
"text": "Use Node.js."
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"kind": "Prompt",
|
|
77
|
+
"hash": "sha256:416a3efe045d89a00fa0cca4516b8bdd442a8f65a42e35a5c102067f3ecb429d",
|
|
78
|
+
"title": "System prompt",
|
|
79
|
+
"language": "en",
|
|
80
|
+
"text": "Keep changes minimal."
|
|
81
|
+
}
|
|
45
82
|
],
|
|
46
83
|
"matrix": [
|
|
47
|
-
{
|
|
84
|
+
{
|
|
85
|
+
"nodeId": "p.web",
|
|
86
|
+
"concern": "Interfaces",
|
|
87
|
+
"documentRefs": [
|
|
88
|
+
"sha256:77760f8cb9fdaaadd3c22612d97fba630f78730c8d750c6cce02754b689b11da"
|
|
89
|
+
],
|
|
90
|
+
"skillRefs": []
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"systemPromptRefs": [
|
|
94
|
+
"sha256:416a3efe045d89a00fa0cca4516b8bdd442a8f65a42e35a5c102067f3ecb429d"
|
|
48
95
|
],
|
|
49
|
-
"systemPromptRefs": ["sha256:416a3efe045d89a00fa0cca4516b8bdd442a8f65a42e35a5c102067f3ecb429d"],
|
|
50
96
|
"artifacts": [
|
|
51
|
-
{
|
|
97
|
+
{
|
|
98
|
+
"id": "a.web.code",
|
|
99
|
+
"nodeId": "p.web",
|
|
100
|
+
"concern": "Implementation",
|
|
101
|
+
"type": "Code",
|
|
102
|
+
"sourcePaths": [
|
|
103
|
+
"app/page.js"
|
|
104
|
+
]
|
|
105
|
+
}
|
|
52
106
|
]
|
|
53
|
-
}
|
|
54
|
-
|
|
107
|
+
},
|
|
108
|
+
"layers": [
|
|
109
|
+
{
|
|
110
|
+
"rootNodeId": "s.root",
|
|
111
|
+
"nodes": [
|
|
112
|
+
{
|
|
113
|
+
"id": "s.root",
|
|
114
|
+
"kind": "Root",
|
|
115
|
+
"name": "Example",
|
|
116
|
+
"metadata": {
|
|
117
|
+
"ownership": "first_party"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "h.runtime",
|
|
122
|
+
"kind": "Host",
|
|
123
|
+
"name": "Application runtime",
|
|
124
|
+
"parentId": "s.root",
|
|
125
|
+
"metadata": {
|
|
126
|
+
"ownership": "first_party"
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "p.web",
|
|
131
|
+
"kind": "Process",
|
|
132
|
+
"name": "Web process",
|
|
133
|
+
"parentId": "h.runtime",
|
|
134
|
+
"sourceSelectors": [
|
|
135
|
+
"app/**"
|
|
136
|
+
],
|
|
137
|
+
"metadata": {
|
|
138
|
+
"ownership": "first_party"
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"id": "l.config",
|
|
143
|
+
"kind": "Library",
|
|
144
|
+
"name": "Project configuration",
|
|
145
|
+
"sourceSelectors": [
|
|
146
|
+
"package.json"
|
|
147
|
+
],
|
|
148
|
+
"metadata": {
|
|
149
|
+
"ownership": "third_party"
|
|
150
|
+
},
|
|
151
|
+
"parentId": "s.root"
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
"edges": [
|
|
155
|
+
{
|
|
156
|
+
"id": "e.web.config",
|
|
157
|
+
"type": "Dependency",
|
|
158
|
+
"fromNodeId": "p.web",
|
|
159
|
+
"toNodeId": "l.config"
|
|
160
|
+
}
|
|
161
|
+
],
|
|
162
|
+
"id": "technical",
|
|
163
|
+
"name": "Technical",
|
|
164
|
+
"role": "technical"
|
|
165
|
+
}
|
|
166
|
+
],
|
|
167
|
+
"refinements": []
|
|
168
|
+
},
|
|
169
|
+
"systemsVersion": "2.0"
|
|
55
170
|
}
|
|
@@ -1,98 +1,101 @@
|
|
|
1
|
-
# OpenShip Systems
|
|
1
|
+
# OpenShip Systems 2.0
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Systems publishes one JSON document containing a complete Sources snapshot, ordered design layers, explicit implementation mappings, optional instance descriptions, and shared context. Systems 2.0 replaces the previous single-graph format; legacy Systems documents are unsupported. Sources and Changes remain OpenShip 1.0.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Top-level document
|
|
5
|
+
## Envelope and system
|
|
8
6
|
|
|
9
7
|
```json
|
|
10
8
|
{
|
|
11
9
|
"openship": "1.0",
|
|
12
10
|
"capability": "systems",
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
"bundle": { "openship": "1.0", "capability": "sources", "digest": "sha256:...", "files": {} }
|
|
16
|
-
},
|
|
11
|
+
"systemsVersion": "2.0",
|
|
12
|
+
"source": { "manifest": {}, "bundle": {} },
|
|
17
13
|
"system": {
|
|
18
|
-
"id": "example
|
|
19
|
-
"name": "Example
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
14
|
+
"id": "example",
|
|
15
|
+
"name": "Example",
|
|
16
|
+
"layers": [],
|
|
17
|
+
"refinements": [],
|
|
18
|
+
"instances": []
|
|
23
19
|
}
|
|
24
20
|
}
|
|
25
21
|
```
|
|
26
22
|
|
|
27
|
-
`source.manifest` and `source.bundle` MUST
|
|
23
|
+
This illustrates the envelope only: `source.manifest` and `source.bundle` MUST be valid, complete Sources, and `layers` MUST contain at least one layer. See [the complete layered example](examples/valid/systems-layered.json) and [the schema](schemas/systems.schema.json).
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
The old `system.nodes`, `system.edges`, and `system.rootNodeId` members are forbidden. Metadata and unrecognized extension members MUST be preserved. Self-containment covers the design and source bytes; external secret and runtime-state references need not resolve within the document. Consumers MUST NOT interpret validation as proof of deployment or runtime health.
|
|
30
26
|
|
|
31
|
-
##
|
|
27
|
+
## Ordered design layers
|
|
32
28
|
|
|
33
|
-
|
|
29
|
+
Each layer has `id`, `name`, `role`, `rootNodeId`, `nodes`, and `edges`. Array order runs from abstract to concrete. Layer IDs MUST be unique. Roles are `logical`, `technical`, `provider`, or `custom`; roles MAY repeat and standard roles MAY be omitted.
|
|
34
30
|
|
|
35
|
-
|
|
|
31
|
+
| Recommended role | Decisions represented |
|
|
36
32
|
|---|---|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
| logical | Responsibilities, contracts, logical entities and invariants, required initial data. |
|
|
34
|
+
| technical | Frameworks, runtimes, database engines, schemas, migrations and seed scripts. |
|
|
35
|
+
| provider | Hosting providers, intended regions, resources and deployment settings. |
|
|
36
|
+
|
|
37
|
+
Any positive number of layers is supported. Each is an explicit graph, not a generated projection or an inherited configuration overlay. Alternative branches are not defined in this version.
|
|
42
38
|
|
|
43
|
-
|
|
39
|
+
## Nodes, containment and sources
|
|
40
|
+
|
|
41
|
+
Node kinds are `Root`, `Block`, `Store`, `Host`, `Container`, `Process`, and `Library`. Block describes a capability; Store describes persistent data. The other kinds describe a system boundary, execution environment, grouped runtime, executable component, and reusable dependency respectively.
|
|
44
42
|
|
|
45
43
|
```json
|
|
46
44
|
{
|
|
47
|
-
"id": "
|
|
48
|
-
"kind": "
|
|
49
|
-
"name": "
|
|
50
|
-
"parentId": "
|
|
51
|
-
"
|
|
52
|
-
"
|
|
45
|
+
"id": "technical.database",
|
|
46
|
+
"kind": "Store",
|
|
47
|
+
"name": "PostgreSQL database",
|
|
48
|
+
"parentId": "technical.root",
|
|
49
|
+
"metadata": { "ownership": "first_party" },
|
|
50
|
+
"sourceSelectors": ["db/**"],
|
|
51
|
+
"configuration": [
|
|
52
|
+
{ "name": "engine", "description": "Database engine", "required": true, "value": "PostgreSQL" }
|
|
53
|
+
]
|
|
53
54
|
}
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
- Node IDs MUST be globally unique across all layers. IDs match `^[A-Za-z0-9._:-]+$`.
|
|
58
|
+
- Each layer MUST have exactly one parentless Root identified by its `rootNodeId`. Every other node, including Library, MUST have a parent in the same layer. Containment MUST be acyclic; no kind-specific parent restrictions apply.
|
|
59
|
+
- Every node MUST declare `metadata.ownership`: `first_party` means publisher-controlled implementation or operation; `third_party` means external control.
|
|
60
|
+
- Optional source selectors select an exact Manifest path or a directory ending in `/**`. No other wildcards are supported. Every selector MUST match at least one Manifest path. Sharing selected paths is allowed.
|
|
61
|
+
|
|
62
|
+
## Connections and refinements
|
|
57
63
|
|
|
58
|
-
-
|
|
59
|
-
- `first_party` means the system publisher owns or controls the component's implementation or operation. `third_party` means an external provider owns or controls it.
|
|
60
|
-
- Exactly one node has kind `Root`; its ID equals `rootNodeId` and it has no parent.
|
|
61
|
-
- Every Host has the Root as parent.
|
|
62
|
-
- Every Container has a Host parent.
|
|
63
|
-
- Every Process has a Host or Container parent.
|
|
64
|
-
- Library has no parent. Process and Library cannot contain children.
|
|
65
|
-
- IDs are unique and match `^[A-Za-z0-9._:-]+$`.
|
|
66
|
-
- The containment graph is acyclic.
|
|
67
|
-
- Metadata is open-ended beyond the required, typed `ownership` member. Boundary, ID prefixes, host naming, and other metadata are not required by v1.
|
|
64
|
+
Layer-local edges have `id`, `type`, `fromNodeId`, `toNodeId`, and optional metadata. IDs MUST be unique within their layer. Endpoints MUST be non-root nodes in that layer. Types are Runtime (cycles allowed), Dataflow (acyclic), and Dependency (acyclic). Endpoint kinds do not constrain the connection type.
|
|
68
65
|
|
|
69
|
-
|
|
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.
|
|
70
67
|
|
|
71
|
-
|
|
68
|
+
## Configuration
|
|
72
69
|
|
|
73
|
-
|
|
70
|
+
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.
|
|
74
71
|
|
|
75
|
-
|
|
72
|
+
A sensitive entry uses `sensitive: true` and MUST NOT contain a literal value. An optional `secretRef` is `{ "nodeId": "provider.app", "key": "DATABASE_URL" }`; its node MUST exist and scopes the external key to a component. Any entry with `secretRef` MUST NOT also contain `value`. A secret reference is descriptive: validation does not resolve it or require the external key to exist. Producers MUST classify credentials as sensitive and MUST NOT publish credential values elsewhere in metadata or context.
|
|
76
73
|
|
|
77
|
-
|
|
74
|
+
## Instances and database state
|
|
78
75
|
|
|
79
|
-
|
|
80
|
-
|---|---|---|---|
|
|
81
|
-
| `Runtime` | Process | Process or Container | Cycles allowed. |
|
|
82
|
-
| `Dataflow` | Process | Process or Container | Projected graph must be acyclic. |
|
|
83
|
-
| `Dependency` | Process | Library | Graph must be acyclic. |
|
|
76
|
+
Instances are separate from design layers. Each has a unique `id`, `name`, `environment`, `layerId`, and `bindings` array. Multiple instances MAY bind the same layer. Each binding refers to a distinct non-root node in that layer and MAY include `resourceId`, configuration, and database `state`. Missing resource IDs are unresolved.
|
|
84
77
|
|
|
85
78
|
```json
|
|
86
79
|
{
|
|
87
|
-
"id": "
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
80
|
+
"id": "production",
|
|
81
|
+
"name": "Production target",
|
|
82
|
+
"environment": "production",
|
|
83
|
+
"layerId": "provider",
|
|
84
|
+
"bindings": [{
|
|
85
|
+
"nodeId": "provider.database",
|
|
86
|
+
"configuration": [{
|
|
87
|
+
"name": "DATABASE_URL", "description": "Database connection", "required": true,
|
|
88
|
+
"sensitive": true, "secretRef": { "nodeId": "provider.database", "key": "DATABASE_URL" }
|
|
89
|
+
}]
|
|
90
|
+
}]
|
|
92
91
|
}
|
|
93
92
|
```
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
Instance values are explicit observations or supplied descriptions, never implicit overrides of intended design values. Consumers SHOULD display them separately.
|
|
95
|
+
|
|
96
|
+
Only Store bindings may include state. State MAY contain `appliedMigration` and a `snapshot` object with required `ref` and RFC3339 `capturedAt`, and optional `sha256:...` digest. Omitted state means not supplied, not an empty database. References are opaque identifiers; consumers MUST NOT automatically fetch or restore them.
|
|
97
|
+
|
|
98
|
+
Logical entities and invariants belong in shared Data Model documents assigned to Store nodes. Technical schema, migration and seed files use source selectors or Code artifacts. Actual database records are not required. A snapshot reference does not establish that a deployment currently contains that state.
|
|
96
99
|
|
|
97
100
|
## Optional context
|
|
98
101
|
|
|
@@ -139,11 +142,11 @@ kind + "\n" + title + "\n" + language + "\n" + text
|
|
|
139
142
|
|
|
140
143
|
Matrix assignments connect a node, a declared concern, and one or more `Document` or `Skill` hashes. References MUST resolve to documents of the corresponding kind.
|
|
141
144
|
|
|
142
|
-
Prompts are not ordinary matrix references. `systemPromptRefs` belongs to context, references only `Prompt` documents, and applies
|
|
145
|
+
Prompts are not ordinary matrix references. `systemPromptRefs` belongs to context, references only `Prompt` documents, and applies to the overall system.
|
|
143
146
|
|
|
144
147
|
### Artifacts
|
|
145
148
|
|
|
146
|
-
Artifact types are `Summary`, `Docs`, and `Code`. Each belongs to one node and one declared concern.
|
|
149
|
+
Artifact types are `Summary`, `Docs`, and `Code`. Each belongs to one globally identified node and one declared concern.
|
|
147
150
|
|
|
148
151
|
- Summary and Docs carry UTF-8 `text` and optional language.
|
|
149
152
|
- Code carries `sourcePaths` that resolve to Manifest files.
|
|
@@ -153,13 +156,11 @@ Artifact IDs are unique within the system.
|
|
|
153
156
|
|
|
154
157
|
## Validation order
|
|
155
158
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
5. Concern declarations and document hashes.
|
|
163
|
-
6. Matrix, prompt, artifact, and supersession references.
|
|
159
|
+
1. Envelope, Systems version, and embedded Sources integrity.
|
|
160
|
+
2. Layer IDs, global node IDs, roots, containment, configuration and source selectors.
|
|
161
|
+
3. Layer-local edges and cycle checks.
|
|
162
|
+
4. Refinement endpoints and order.
|
|
163
|
+
5. Instance membership, bindings, configuration, state and secret scopes.
|
|
164
|
+
6. Shared document hashes, concerns, matrix/artifact references, prompts and supersession chains.
|
|
164
165
|
|
|
165
|
-
Unknown
|
|
166
|
+
Unknown node, edge, document, artifact or layer-role values are invalid. Use the `custom` role for additional refinement levels.
|
|
@@ -7,7 +7,7 @@ OpenShip is a public interface between a running project and the people or agent
|
|
|
7
7
|
|
|
8
8
|
1. **Sources** publishes an integrity-checked source snapshot.
|
|
9
9
|
2. **Changes** accepts a patch against a Sources digest and produces an isolated candidate origin.
|
|
10
|
-
3. **Systems** publishes a self-contained JSON description of source,
|
|
10
|
+
3. **Systems** publishes a self-contained JSON description of source, ordered design layers, instance bindings, and optional agent context. Systems uses the additional `systemsVersion: "2.0"` discriminator.
|
|
11
11
|
|
|
12
12
|
Sources is the foundation. Changes depends on Sources. Systems embeds a complete Sources snapshot but does not require Changes.
|
|
13
13
|
|