chore(v2): establish protocol and test foundation

This commit is contained in:
2026-07-27 18:44:47 +02:00
parent 33b0c21292
commit 791f4526f9
86 changed files with 4060 additions and 2582 deletions
@@ -0,0 +1,14 @@
{
"api_version": "v2",
"sources": ["local", "ssh"],
"repositories": ["local"],
"features": {
"email": true,
"encryption": true,
"mysql": false,
"postgresql": false,
"restore": true,
"tar_download": false,
"webhook": true
}
}
+22
View File
@@ -0,0 +1,22 @@
[
"authentication_failed",
"baseline_missing",
"cancelled_by_operator",
"capacity_exhausted",
"conflict_active_execution",
"corrupt_blob",
"corrupt_manifest",
"deletion_failed",
"forbidden",
"host_key_changed",
"host_key_unknown",
"invalid_configuration",
"not_found",
"permission_denied",
"source_changed",
"source_empty",
"timeout",
"transient_io",
"unsupported_entry",
"worker_lost"
]
@@ -0,0 +1,10 @@
{
"queued": ["cancelled", "preparing"],
"preparing": ["cancelling", "failed", "running"],
"running": ["cancelling", "failed", "verifying"],
"verifying": ["committed", "failed"],
"cancelling": ["cancelled", "failed"],
"committed": [],
"failed": [],
"cancelled": []
}
+14
View File
@@ -0,0 +1,14 @@
[
"blob.before_write",
"blob.after_write",
"blob.after_fsync",
"blob.before_rename",
"manifest.before_write",
"manifest.after_fsync",
"manifest.before_publish",
"metadata.before_commit",
"metadata.after_commit",
"restore.before_write",
"restore.after_fsync",
"restore.before_replace"
]
@@ -0,0 +1 @@
{"aggregates":{"entry_count":-1,"logical_bytes":-5,"stored_bytes":0},"backup_id":"bad","created_at":"not-a-time","effective_mode":"full","encryption_key_id":null,"entries":[],"exclusion_policy":{"matcher":"glob","patterns":[],"version":0},"execution_id":"bad","format_version":2,"job_id":"bad","manifest_digest":"short","repository_id":"bad","requested_mode":"full","source_consistency":{},"source_id":"bad"}
@@ -0,0 +1 @@
{"compression":"none","created_at":"2026-07-27T00:00:00Z","digest_algorithm":"md5","encryption":{"key_id":null,"mode":"none"},"format_version":2,"repository_id":"not-a-uuid"}
@@ -0,0 +1 @@
{"aggregates":{"entry_count":2,"logical_bytes":5,"stored_bytes":5},"backup_id":"0198c57f-0000-7000-8000-000000000006","created_at":"2026-07-27T00:00:00Z","effective_mode":"full","encryption_key_id":null,"entries":[{"blob_digest":null,"link_target":null,"metadata_support":["mode","mtime_ns"],"mode":493,"mtime_ns":0,"path":"data","size":0,"type":"directory"},{"blob_digest":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","link_target":null,"metadata_support":["mode","mtime_ns"],"mode":420,"mtime_ns":0,"path":"data/hello.txt","size":5,"type":"file"}],"exclusion_policy":{"matcher":"gitignore","patterns":[],"version":1},"execution_id":"0198c57f-0000-7000-8000-000000000005","format_version":1,"job_id":"0198c57f-0000-7000-8000-000000000004","manifest_digest":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","repository_id":"0198c57f-0000-7000-8000-000000000001","requested_mode":"full","source_consistency":{"adapter":"local","captured_at":"2026-07-27T00:00:00Z"},"source_id":"0198c57f-0000-7000-8000-000000000003"}
@@ -0,0 +1 @@
{"compression":"none","created_at":"2026-07-27T00:00:00Z","digest_algorithm":"sha256","encryption":{"key_id":null,"mode":"none"},"format_version":1,"repository_id":"0198c57f-0000-7000-8000-000000000001"}
@@ -0,0 +1,67 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://backup-tool.invalid/contracts/repository/v1/manifest.schema.json",
"title": "Backup Tool Manifest v1",
"type": "object",
"additionalProperties": false,
"required": [
"format_version", "backup_id", "repository_id", "source_id", "job_id", "execution_id",
"requested_mode", "effective_mode", "created_at", "source_consistency", "exclusion_policy",
"entries", "aggregates", "encryption_key_id", "manifest_digest"
],
"properties": {
"format_version": {"const": 1},
"backup_id": {"type": "string", "format": "uuid"},
"repository_id": {"type": "string", "format": "uuid"},
"source_id": {"type": "string", "format": "uuid"},
"job_id": {"type": "string", "format": "uuid"},
"execution_id": {"type": "string", "format": "uuid"},
"requested_mode": {"enum": ["full", "incremental"]},
"effective_mode": {"enum": ["full", "incremental"]},
"created_at": {"type": "string", "format": "date-time"},
"source_consistency": {"type": "object"},
"exclusion_policy": {
"type": "object",
"additionalProperties": false,
"required": ["matcher", "version", "patterns"],
"properties": {
"matcher": {"const": "gitignore"},
"version": {"type": "integer", "minimum": 1},
"patterns": {"type": "array", "items": {"type": "string"}}
}
},
"entries": {
"type": "array",
"items": {"$ref": "#/$defs/entry"}
},
"aggregates": {
"type": "object",
"additionalProperties": false,
"required": ["entry_count", "logical_bytes", "stored_bytes"],
"properties": {
"entry_count": {"type": "integer", "minimum": 0},
"logical_bytes": {"type": "integer", "minimum": 0},
"stored_bytes": {"type": "integer", "minimum": 0}
}
},
"encryption_key_id": {"type": ["string", "null"]},
"manifest_digest": {"type": "string", "pattern": "^[0-9a-f]{64}$"}
},
"$defs": {
"entry": {
"type": "object",
"additionalProperties": false,
"required": ["path", "type", "size", "blob_digest", "mode", "mtime_ns", "link_target", "metadata_support"],
"properties": {
"path": {"type": "string", "minLength": 1, "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\).+$"},
"type": {"enum": ["file", "directory", "symlink"]},
"size": {"type": "integer", "minimum": 0},
"blob_digest": {"type": ["string", "null"], "pattern": "^[0-9a-f]{64}$"},
"mode": {"type": ["integer", "null"], "minimum": 0},
"mtime_ns": {"type": ["integer", "null"], "minimum": 0},
"link_target": {"type": ["string", "null"]},
"metadata_support": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}
}
}
}
}
@@ -0,0 +1,9 @@
[
{"raw": "file.txt", "normalized": "file.txt", "valid": true},
{"raw": "dir/./file.txt", "normalized": "dir/file.txt", "valid": true},
{"raw": "unicodé/文件.txt", "normalized": "unicodé/文件.txt", "valid": true},
{"raw": "/absolute", "normalized": null, "valid": false},
{"raw": "../escape", "normalized": null, "valid": false},
{"raw": "a\\b", "normalized": null, "valid": false},
{"raw": "", "normalized": null, "valid": false}
]
@@ -0,0 +1,24 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://backup-tool.invalid/contracts/repository/v1/repository.schema.json",
"title": "Backup Tool Repository v1",
"type": "object",
"additionalProperties": false,
"required": ["repository_id", "format_version", "digest_algorithm", "compression", "encryption", "created_at"],
"properties": {
"repository_id": {"type": "string", "format": "uuid"},
"format_version": {"const": 1},
"digest_algorithm": {"const": "sha256"},
"compression": {"enum": ["none", "zstd"]},
"encryption": {
"type": "object",
"additionalProperties": false,
"required": ["mode", "key_id"],
"properties": {
"mode": {"enum": ["none", "aes-256-gcm"]},
"key_id": {"type": ["string", "null"], "minLength": 1}
}
},
"created_at": {"type": "string", "format": "date-time"}
}
}