@vev-software/atlas-contracts 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.
@@ -0,0 +1,218 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://contracts.vev.software/atlas/v1/discovery-observation.schema.json",
4
+ "title": "Atlas discovery observation batch (v1)",
5
+ "description": "The public wire format a discovery scanner emits INTO Atlas: a batch of raw observations of an IT landscape (servers, applications, infrastructure) that the private Atlas Enterprise reconciliation engine correlates, deduplicates and turns into catalogue assets. This contract carries facts only — an observation has no Atlas 'id' and no 'lifecycle' (the reconciler assigns those), and never any analysis (no EOL/risk, no criticality, no portfolio scoring). Open so third parties can build scanners; the reconciliation logic that consumes it is the private moat and is NOT part of this repo. See handbook 11 §3, 12 §Phase A, and vev-software/atlas-enterprise#6/#9.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["contractVersion", "kind", "source", "observedAt", "observations"],
9
+ "properties": {
10
+ "contractVersion": {
11
+ "type": "string",
12
+ "description": "The atlas-contracts schema major version this batch conforms to.",
13
+ "const": "1"
14
+ },
15
+ "kind": {
16
+ "type": "string",
17
+ "description": "Discriminates a discovery observation batch from the import/export documents.",
18
+ "const": "discovery-observation"
19
+ },
20
+ "source": {
21
+ "description": "Provenance of the batch: which scanner produced it and how.",
22
+ "$ref": "#/$defs/ObservationSource"
23
+ },
24
+ "observedAt": {
25
+ "type": "string",
26
+ "description": "When the scan that produced this batch was taken.",
27
+ "format": "date-time"
28
+ },
29
+ "observations": {
30
+ "type": "array",
31
+ "description": "The raw observations in this batch. May be empty (a scan that saw nothing new).",
32
+ "items": { "$ref": "#/$defs/Observation" },
33
+ "default": []
34
+ }
35
+ },
36
+ "$defs": {
37
+ "ObservationSource": {
38
+ "type": "object",
39
+ "description": "Which scanner produced the batch. The authoritative tenant binding is the authenticated machine-principal at ingestion (a Fabric concern), NOT this payload; 'tenantRef' is an optional, opaque hint only.",
40
+ "additionalProperties": false,
41
+ "required": ["agentId", "method"],
42
+ "properties": {
43
+ "agentId": {
44
+ "type": "string",
45
+ "description": "Stable identifier of the emitting agent or collector. Constant across scans so the reconciler can attribute observations to a source.",
46
+ "minLength": 1,
47
+ "maxLength": 256
48
+ },
49
+ "method": {
50
+ "type": "string",
51
+ "description": "How the batch was collected: an installed 'agent' in the landscape, or 'agentless' remote scanning from a collector.",
52
+ "enum": ["agent", "agentless"]
53
+ },
54
+ "version": {
55
+ "type": ["string", "null"],
56
+ "description": "The scanner's version, if known.",
57
+ "maxLength": 64
58
+ },
59
+ "tenantRef": {
60
+ "type": ["string", "null"],
61
+ "description": "Optional opaque tenant hint. Not authoritative — ingestion binds tenancy from the authenticated principal.",
62
+ "maxLength": 256
63
+ }
64
+ }
65
+ },
66
+ "Observation": {
67
+ "type": "object",
68
+ "description": "A single raw sighting of something in the landscape. Facts only: no Atlas 'id' and no 'lifecycle' (the private reconciler assigns identity and catalogue state), and no analysis. Kind-specific held facts reuse the catalogue vocabulary; discovery-only facts (ports/processes/packages) are additional observations, not catalogue analysis.",
69
+ "unevaluatedProperties": false,
70
+ "required": ["observedId", "kind", "name"],
71
+ "properties": {
72
+ "observedId": {
73
+ "type": "string",
74
+ "description": "A scanner-local identifier for the observed thing, stable across scans from the same source. NOT an Atlas asset id — the reconciler decides the catalogue identity.",
75
+ "minLength": 1,
76
+ "maxLength": 256
77
+ },
78
+ "kind": { "$ref": "common.schema.json#/$defs/AssetKind" },
79
+ "name": {
80
+ "type": "string",
81
+ "minLength": 1,
82
+ "maxLength": 256
83
+ },
84
+ "fingerprint": {
85
+ "type": "array",
86
+ "description": "Durable attributes the reconciler may correlate on (e.g. machine-id, MAC, serial, cloud instance id) — deliberately more than a hostname. Carried as facts; how they are weighted for matching is private reconciler logic, not part of this contract.",
87
+ "items": { "$ref": "#/$defs/FingerprintAttribute" },
88
+ "default": []
89
+ },
90
+ "ports": {
91
+ "type": "array",
92
+ "description": "Observed listening ports (a fact, not an integration map).",
93
+ "items": { "$ref": "#/$defs/ObservedPort" },
94
+ "default": []
95
+ },
96
+ "processes": {
97
+ "type": "array",
98
+ "description": "Observed running processes / services (facts).",
99
+ "items": { "$ref": "#/$defs/ObservedProcess" },
100
+ "default": []
101
+ },
102
+ "packages": {
103
+ "type": "array",
104
+ "description": "Observed installed runtimes / packages (facts).",
105
+ "items": { "$ref": "#/$defs/ObservedPackage" },
106
+ "default": []
107
+ },
108
+ "tags": {
109
+ "type": "array",
110
+ "description": "Observed lightweight labels (e.g. a cloud resource tag).",
111
+ "items": { "$ref": "common.schema.json#/$defs/Tag" },
112
+ "default": []
113
+ },
114
+ "firstSeen": {
115
+ "type": ["string", "null"],
116
+ "description": "When the source first saw this thing, if tracked.",
117
+ "format": "date-time"
118
+ },
119
+ "lastSeen": {
120
+ "type": ["string", "null"],
121
+ "description": "When the source most recently saw this thing, if tracked.",
122
+ "format": "date-time"
123
+ }
124
+ },
125
+ "allOf": [
126
+ {
127
+ "if": { "properties": { "kind": { "const": "application" } } },
128
+ "then": { "properties": { "application": { "$ref": "common.schema.json#/$defs/ApplicationDetails" } } }
129
+ },
130
+ {
131
+ "if": { "properties": { "kind": { "const": "server" } } },
132
+ "then": { "properties": { "server": { "$ref": "common.schema.json#/$defs/ServerDetails" } } }
133
+ },
134
+ {
135
+ "if": { "properties": { "kind": { "const": "infrastructure" } } },
136
+ "then": { "properties": { "infrastructure": { "$ref": "common.schema.json#/$defs/InfrastructureDetails" } } }
137
+ }
138
+ ]
139
+ },
140
+ "FingerprintAttribute": {
141
+ "type": "object",
142
+ "description": "One durable correlation attribute: a key and its observed value (both required — unlike a Tag, a fingerprint carries no valueless keys).",
143
+ "additionalProperties": false,
144
+ "required": ["key", "value"],
145
+ "properties": {
146
+ "key": {
147
+ "type": "string",
148
+ "minLength": 1,
149
+ "maxLength": 64,
150
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._/-]*$"
151
+ },
152
+ "value": {
153
+ "type": "string",
154
+ "minLength": 1,
155
+ "maxLength": 512
156
+ }
157
+ }
158
+ },
159
+ "ObservedPort": {
160
+ "type": "object",
161
+ "description": "An observed listening port. A recorded fact; not a measured integration.",
162
+ "additionalProperties": false,
163
+ "required": ["port"],
164
+ "properties": {
165
+ "port": {
166
+ "type": "integer",
167
+ "minimum": 1,
168
+ "maximum": 65535
169
+ },
170
+ "protocol": {
171
+ "type": ["string", "null"],
172
+ "enum": ["tcp", "udp", null]
173
+ },
174
+ "address": {
175
+ "type": ["string", "null"],
176
+ "description": "The bind address the port was seen on, if known.",
177
+ "maxLength": 253
178
+ }
179
+ }
180
+ },
181
+ "ObservedProcess": {
182
+ "type": "object",
183
+ "description": "An observed running process or service. A recorded fact.",
184
+ "additionalProperties": false,
185
+ "required": ["name"],
186
+ "properties": {
187
+ "name": {
188
+ "type": "string",
189
+ "minLength": 1,
190
+ "maxLength": 256
191
+ },
192
+ "port": {
193
+ "type": ["integer", "null"],
194
+ "description": "The port the process was seen listening on, if known.",
195
+ "minimum": 1,
196
+ "maximum": 65535
197
+ }
198
+ }
199
+ },
200
+ "ObservedPackage": {
201
+ "type": "object",
202
+ "description": "An observed installed runtime or package. A recorded fact; the version is what was seen, not an EOL/risk assessment (that is paid Atlas core).",
203
+ "additionalProperties": false,
204
+ "required": ["name"],
205
+ "properties": {
206
+ "name": {
207
+ "type": "string",
208
+ "minLength": 1,
209
+ "maxLength": 256
210
+ },
211
+ "version": {
212
+ "type": ["string", "null"],
213
+ "maxLength": 128
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
@@ -0,0 +1,104 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://contracts.vev.software/atlas/v1/import.schema.json",
4
+ "title": "Atlas import bundle (v1)",
5
+ "description": "The import side of the portability surface: a batch of catalogue assets and manual relationships moved INTO Atlas. Unlike an export, assets may omit their Atlas 'id' (the runtime assigns one) and instead carry an importer-supplied 'externalId' used to resolve references and match on re-import. Catalogue data only — no paid-core analysis. See handbook 11 §2-3.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["contractVersion", "kind", "assets"],
9
+ "properties": {
10
+ "contractVersion": {
11
+ "type": "string",
12
+ "description": "The atlas-contracts schema major version this bundle conforms to.",
13
+ "const": "1"
14
+ },
15
+ "kind": {
16
+ "type": "string",
17
+ "description": "Discriminates an import bundle from an export document.",
18
+ "const": "import"
19
+ },
20
+ "mode": {
21
+ "type": "string",
22
+ "description": "How the bundle applies to the existing catalogue. 'merge' upserts by identifier; 'replace' makes the target match the bundle. The runtime enforces the semantics; this only records intent.",
23
+ "enum": ["merge", "replace"],
24
+ "default": "merge"
25
+ },
26
+ "assets": {
27
+ "type": "array",
28
+ "items": { "$ref": "#/$defs/ImportAsset" }
29
+ },
30
+ "relationships": {
31
+ "type": "array",
32
+ "items": { "$ref": "#/$defs/ImportRelationship" },
33
+ "default": []
34
+ }
35
+ },
36
+ "$defs": {
37
+ "ImportAsset": {
38
+ "type": "object",
39
+ "description": "An asset to import. Must carry at least one of 'id' (an existing Atlas id) or 'externalId' (a source-system id), so it can be matched and referenced.",
40
+ "unevaluatedProperties": false,
41
+ "required": ["kind", "name", "lifecycle"],
42
+ "anyOf": [
43
+ { "required": ["id"] },
44
+ { "required": ["externalId"] }
45
+ ],
46
+ "properties": {
47
+ "id": { "$ref": "common.schema.json#/$defs/AssetId" },
48
+ "externalId": { "$ref": "common.schema.json#/$defs/ExternalId" },
49
+ "kind": { "$ref": "common.schema.json#/$defs/AssetKind" },
50
+ "name": { "type": "string", "minLength": 1, "maxLength": 256 },
51
+ "description": { "type": ["string", "null"], "maxLength": 4096 },
52
+ "lifecycle": { "$ref": "common.schema.json#/$defs/Lifecycle" },
53
+ "tags": {
54
+ "type": "array",
55
+ "items": { "$ref": "common.schema.json#/$defs/Tag" },
56
+ "default": []
57
+ }
58
+ },
59
+ "allOf": [
60
+ {
61
+ "if": { "properties": { "kind": { "const": "application" } } },
62
+ "then": { "properties": { "application": { "$ref": "common.schema.json#/$defs/ApplicationDetails" } } }
63
+ },
64
+ {
65
+ "if": { "properties": { "kind": { "const": "server" } } },
66
+ "then": { "properties": { "server": { "$ref": "common.schema.json#/$defs/ServerDetails" } } }
67
+ },
68
+ {
69
+ "if": { "properties": { "kind": { "const": "infrastructure" } } },
70
+ "then": { "properties": { "infrastructure": { "$ref": "common.schema.json#/$defs/InfrastructureDetails" } } }
71
+ },
72
+ {
73
+ "if": { "properties": { "kind": { "const": "data-area" } } },
74
+ "then": { "properties": { "dataArea": { "$ref": "common.schema.json#/$defs/DataAreaDetails" } } }
75
+ },
76
+ {
77
+ "if": { "properties": { "kind": { "const": "dataset" } } },
78
+ "then": { "properties": { "dataset": { "$ref": "common.schema.json#/$defs/DatasetDetails" } } }
79
+ },
80
+ {
81
+ "if": { "properties": { "kind": { "const": "column" } } },
82
+ "then": { "properties": { "column": { "$ref": "common.schema.json#/$defs/ColumnDetails" } } }
83
+ }
84
+ ]
85
+ },
86
+ "ImportRelationship": {
87
+ "type": "object",
88
+ "description": "A manual relationship to import. Endpoints are references (asset 'id' or 'externalId' present in this bundle), resolved by the runtime and checked by the conformance kit.",
89
+ "additionalProperties": false,
90
+ "required": ["fromRef", "toRef", "type"],
91
+ "properties": {
92
+ "id": { "$ref": "common.schema.json#/$defs/AssetId" },
93
+ "fromRef": { "$ref": "common.schema.json#/$defs/Ref" },
94
+ "toRef": { "$ref": "common.schema.json#/$defs/Ref" },
95
+ "type": {
96
+ "type": "string",
97
+ "description": "The manual relationship vocabulary. Mirrors relationship.schema.json.",
98
+ "enum": ["runs-on", "hosts", "connects-to", "depends-on", "part-of", "joins-on"]
99
+ },
100
+ "description": { "type": ["string", "null"], "maxLength": 1024 }
101
+ }
102
+ }
103
+ }
104
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://contracts.vev.software/atlas/v1/landscape.schema.json",
4
+ "title": "Atlas landscape document — the export format (v1)",
5
+ "description": "The export side of the portability surface: a whole landscape (assets + manual relationships) carried across a boundary as a self-consistent, resolved document. Backs customer-owned data export and community exporters. The matching import side is import.schema.json. See handbook 11 §2-3, 12 §Phase C.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["contractVersion", "assets"],
9
+ "properties": {
10
+ "contractVersion": {
11
+ "type": "string",
12
+ "description": "The atlas-contracts schema major version this document conforms to.",
13
+ "const": "1"
14
+ },
15
+ "exportedAt": {
16
+ "type": ["string", "null"],
17
+ "format": "date-time"
18
+ },
19
+ "generator": {
20
+ "description": "Optional provenance: what produced this export.",
21
+ "oneOf": [
22
+ { "type": "null" },
23
+ { "$ref": "common.schema.json#/$defs/Generator" }
24
+ ]
25
+ },
26
+ "assets": {
27
+ "type": "array",
28
+ "items": { "$ref": "asset.schema.json" }
29
+ },
30
+ "relationships": {
31
+ "type": "array",
32
+ "items": { "$ref": "relationship.schema.json" },
33
+ "default": []
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://contracts.vev.software/atlas/v1/relationship.schema.json",
4
+ "title": "Atlas relationship (v1)",
5
+ "description": "A manual, catalogue-level typed link between two assets — held data expressing 'what runs on / connects to what'. NOT derived analysis: automatic integration mapping with ownership/criticality is paid Atlas core. See handbook 11 §1.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["id", "fromId", "toId", "type"],
9
+ "properties": {
10
+ "id": { "$ref": "common.schema.json#/$defs/AssetId" },
11
+ "fromId": { "$ref": "common.schema.json#/$defs/AssetId" },
12
+ "toId": { "$ref": "common.schema.json#/$defs/AssetId" },
13
+ "type": {
14
+ "type": "string",
15
+ "description": "The manual relationship vocabulary. Open set of held link types; adding a value is non-breaking. 'part-of' also carries data-layer containment (column → dataset → data-area → system); 'joins-on' is a held cross-dataset join key (nøgle) between columns/datasets, not a measured/derived join.",
16
+ "enum": ["runs-on", "hosts", "connects-to", "depends-on", "part-of", "joins-on"]
17
+ },
18
+ "description": {
19
+ "type": ["string", "null"],
20
+ "maxLength": 1024
21
+ }
22
+ }
23
+ }