Skip to content

Commit f0a968a

Browse files
authored
Create examples.md
1 parent 8bbd5f1 commit f0a968a

1 file changed

Lines changed: 313 additions & 0 deletions

File tree

docs/schemas/examples.md

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
2+
# Examples
3+
4+
This document contains practical examples of SIGNIA v1 bundle artifacts:
5+
- `schema.json` examples (Schema v1)
6+
- `manifest.json` examples (Manifest v1)
7+
- `proof.json` examples (Proof v1)
8+
- end-to-end example bundles you can verify
9+
10+
All JSON blocks below are **illustrative** and may be shortened for readability. When used as fixtures, ensure they are canonicalized per:
11+
- `docs/determinism/canonicalization.md`
12+
- `docs/determinism/hashing.md`
13+
14+
---
15+
16+
## 1) Minimal OpenAPI-derived structure
17+
18+
This example models a single endpoint extracted from an OpenAPI document.
19+
20+
### 1.1 schema.json (minimal)
21+
22+
```json
23+
{
24+
"schema_version": "v1",
25+
"hash_domain": "signia:schema:v1",
26+
"schema_id": "0123012301230123012301230123012301230123012301230123012301230123",
27+
"root": {
28+
"artifact": {
29+
"kind": "openapi",
30+
"name": "Example API",
31+
"namespace": "example",
32+
"ref": "v1",
33+
"labels": ["api", "openapi"]
34+
},
35+
"graph": {
36+
"entities": [
37+
{
38+
"id": "ent:endpoint:GET_/health",
39+
"kind": "endpoint",
40+
"name": "GET /health",
41+
"path": null,
42+
"digest": null,
43+
"attrs": { "method": "GET", "route": "/health" },
44+
"tags": ["public"]
45+
}
46+
],
47+
"edges": [],
48+
"indexes": {}
49+
},
50+
"types": { "definitions": [] },
51+
"constraints": { "rules": [] }
52+
},
53+
"meta": {}
54+
}
55+
```
56+
57+
Notes:
58+
- `schema_id` is shown as a placeholder 32-byte hash in hex.
59+
- `labels` and `tags` are sorted.
60+
61+
### 1.2 manifest.json (minimal)
62+
63+
```json
64+
{
65+
"manifest_version": "v1",
66+
"hash_domain": "signia:manifest:v1",
67+
"bundle": {
68+
"schema_hash": "0123012301230123012301230123012301230123012301230123012301230123",
69+
"proof_root": "4567456745674567456745674567456745674567456745674567456745674567",
70+
"manifest_hash": null,
71+
"schema_version": "v1",
72+
"proof_version": "v1",
73+
"created_by": {
74+
"compiler": "signia",
75+
"compiler_version": "0.1.0",
76+
"build": { "git_commit": null, "build_profile": "release", "target": null }
77+
}
78+
},
79+
"input": {
80+
"source": {
81+
"kind": "file",
82+
"uri": "artifact:/openapi.json",
83+
"resolved": { "commit": null, "checksum": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "etag": null }
84+
},
85+
"descriptor": {
86+
"descriptor_version": "v1",
87+
"descriptor_hash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
88+
"fields": {
89+
"plugin": "openapi",
90+
"plugin_version": "0.1.0",
91+
"normalization_policy": "v1",
92+
"canonicalization_rules": "v1"
93+
}
94+
}
95+
},
96+
"toolchain": {
97+
"compiler": {
98+
"name": "signia",
99+
"version": "0.1.0",
100+
"hash_function": "sha256",
101+
"canonicalization": { "rules_version": "v1" }
102+
},
103+
"plugins": [
104+
{ "name": "openapi", "version": "0.1.0", "config_hash": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "notes": null }
105+
]
106+
},
107+
"policies": {
108+
"normalization": {
109+
"policy_version": "v1",
110+
"path_root": "artifact:/",
111+
"newline": "lf",
112+
"encoding": "utf-8",
113+
"symlinks": "deny",
114+
"network": "deny"
115+
},
116+
"limits": {
117+
"max_total_bytes": 268435456,
118+
"max_file_bytes": 10485760,
119+
"max_files": 20000,
120+
"max_depth": 64,
121+
"max_nodes": 200000,
122+
"max_edges": 400000,
123+
"timeout_ms": 300000
124+
}
125+
},
126+
"dependencies": { "schemas": [] },
127+
"non_hashed": { "display": { "title": "Example API", "description": "" }, "annotations": { "publisher_label": null, "tags": [] } }
128+
}
129+
```
130+
131+
Notes:
132+
- `checksum` is a placeholder.
133+
- `descriptor_hash` and `config_hash` are placeholders.
134+
135+
### 1.3 proof.json (minimal)
136+
137+
```json
138+
{
139+
"proof_version": "v1",
140+
"hash_domain": "signia:proof:v1",
141+
"hash_function": "sha256",
142+
"root": {
143+
"root_hash": "4567456745674567456745674567456745674567456745674567456745674567",
144+
"root_domain": "signia:proof-root:v1",
145+
"tree": { "node_domain": "signia:merkle:node:v1", "odd_leaf_rule": "duplicate_last", "arity": 2 }
146+
},
147+
"leaves": {
148+
"leaf_set": { "leaf_ordering": "type_then_id", "leaf_count": 1, "leaf_commitment": null },
149+
"items": [
150+
{
151+
"kind": "entity",
152+
"id": "ent:endpoint:GET_/health",
153+
"hash": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
154+
"projection": {
155+
"id": "ent:endpoint:GET_/health",
156+
"kind": "endpoint",
157+
"name": "GET /health",
158+
"path": null,
159+
"digest": null,
160+
"attrs": { "method": "GET", "route": "/health" },
161+
"tags": ["public"]
162+
}
163+
}
164+
]
165+
},
166+
"inclusion_proofs": [],
167+
"meta": {}
168+
}
169+
```
170+
171+
---
172+
173+
## 2) Repository structure example (import graph)
174+
175+
This example models a small codebase structure: two modules and an import edge.
176+
177+
### 2.1 schema.json (repo graph)
178+
179+
```json
180+
{
181+
"schema_version": "v1",
182+
"hash_domain": "signia:schema:v1",
183+
"schema_id": "1111111111111111111111111111111111111111111111111111111111111111",
184+
"root": {
185+
"artifact": {
186+
"kind": "repo",
187+
"name": "tiny-repo",
188+
"namespace": "example",
189+
"ref": "commit:deadbeef",
190+
"labels": ["repo"]
191+
},
192+
"graph": {
193+
"entities": [
194+
{
195+
"id": "ent:module:src/main.ts",
196+
"kind": "module",
197+
"name": "src/main.ts",
198+
"path": "artifact:/src/main.ts",
199+
"digest": "2222222222222222222222222222222222222222222222222222222222222222",
200+
"attrs": { "language": "typescript" },
201+
"tags": ["code"]
202+
},
203+
{
204+
"id": "ent:module:src/util.ts",
205+
"kind": "module",
206+
"name": "src/util.ts",
207+
"path": "artifact:/src/util.ts",
208+
"digest": "3333333333333333333333333333333333333333333333333333333333333333",
209+
"attrs": { "language": "typescript" },
210+
"tags": ["code"]
211+
}
212+
],
213+
"edges": [
214+
{
215+
"id": "edge:imports:ent:module:src/main.ts:ent:module:src/util.ts:0",
216+
"relation": "imports",
217+
"from": "ent:module:src/main.ts",
218+
"to": "ent:module:src/util.ts",
219+
"attrs": { "spec": "./util" }
220+
}
221+
],
222+
"indexes": {}
223+
},
224+
"types": { "definitions": [] },
225+
"constraints": { "rules": [] }
226+
},
227+
"meta": {}
228+
}
229+
```
230+
231+
---
232+
233+
## 3) Constraint example (compatibility rule)
234+
235+
This example includes a simple constraint: a schema requires at least one endpoint entity.
236+
237+
```json
238+
{
239+
"id": "c:require-kind:endpoint",
240+
"kind": "require_kind",
241+
"scope": { "entities": [], "types": [] },
242+
"predicate": { "kind": "endpoint", "min_count": 1 },
243+
"severity": "error",
244+
"attrs": {}
245+
}
246+
```
247+
248+
---
249+
250+
## 4) Inclusion proof example (single leaf)
251+
252+
This example shows what an inclusion proof might look like for a leaf.
253+
254+
```json
255+
{
256+
"kind": "entity",
257+
"id": "ent:endpoint:GET_/health",
258+
"leaf_hash": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
259+
"path": [
260+
{ "side": "right", "hash": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" },
261+
{ "side": "left", "hash": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }
262+
]
263+
}
264+
```
265+
266+
Notes:
267+
- `path` is ordered from leaf to root.
268+
- `side` indicates sibling position relative to the current hash at each step.
269+
270+
---
271+
272+
## 5) How to validate these examples locally
273+
274+
Using the SIGNIA CLI (once available in this repository):
275+
276+
- Compile:
277+
- `signia compile --input ./openapi.json --plugin openapi --out ./bundle`
278+
- Verify:
279+
- `signia verify ./bundle`
280+
- Inspect:
281+
- `signia inspect ./bundle --format json`
282+
- Print hash:
283+
- `signia hash ./bundle/schema.json`
284+
285+
Verification steps recompute:
286+
- schema canonical bytes and schema hash
287+
- leaf hashes and Merkle root
288+
- manifest linkage integrity
289+
290+
---
291+
292+
## 6) Fixture guidance (for repository maintainers)
293+
294+
When adding fixtures:
295+
- store fixture input under `fixtures/<name>/input/`
296+
- store expected outputs under `fixtures/<name>/expected/`
297+
- ensure expected JSON files are canonical (no extra whitespace, keys sorted)
298+
- record expected hashes under `fixtures/<name>/expected/hashes.json`
299+
300+
CI should:
301+
- compile fixture twice
302+
- compare outputs byte-for-byte
303+
- run `verify` and fail closed on mismatches
304+
305+
---
306+
307+
## 7) Related documents
308+
309+
- Schema spec: `docs/schemas/schema-v1.md`
310+
- Manifest spec: `docs/schemas/manifest-v1.md`
311+
- Proof spec: `docs/schemas/proof-v1.md`
312+
- Canonicalization: `docs/determinism/canonicalization.md`
313+
- Hashing: `docs/determinism/hashing.md`

0 commit comments

Comments
 (0)