Output contract
The run-manifest schema and the --output json shapes are a stable, versioned public
contract. Build tooling on them. Changes get a new schema version, existing versions keep
verifying.
Object layout (per run)
Section titled “Object layout (per run)”{host}/{org}/{repo}/{YYYY-MM-DD}/{repo}.bundle git data, git bundle --all HEAD{host}/{org}/{repo}/{YYYY-MM-DD}/{repo}.meta.json metadata dump (gitdr.meta/v1){host}/{org}/{repo}/{YYYY-MM-DD}/{repo}.sha256 sha256sum line for the bundle{host}/{org}/{repo}/{YYYY-MM-DD}/{repo}.lfs.tar LFS objects, when present{host}/{org}/manifests/{YYYYMMDDThhmmssZ}.manifest.json signed run-manifest{host}/{org}/manifests/{YYYYMMDDThhmmssZ}.manifest.json.sig detached signatureEvery object is written create-only, under object-lock retention when the bucket has it.
Run-manifest (gitdr.manifest/v2)
Section titled “Run-manifest (gitdr.manifest/v2)”{ "schema": "gitdr.manifest/v2", "runId": "20260613T120000Z-a1b2c3d4e5f6", "tool": { "name": "gitdr", "version": "v0.1.0 (abc123def456)" }, "source": { "type": "github", "host": "github.com" }, "destination": { "type": "s3", "bucket": "my-worm-bucket", "wormMode": "COMPLIANCE", "wormImmutable": true, "wormDetails": "Object Lock enabled; default retention COMPLIANCE" }, "startedAt": "2026-06-13T12:00:00Z", "finishedAt": "2026-06-13T12:03:00Z", "status": "success", "repos": [ { "slug": "octo/hello", "status": "success", "artifacts": [ { "kind": "bundle", "key": "github.com/octo/hello/2026-06-13/hello.bundle", "size": 12345, "sha256": "…", "retainUntil": "2026-07-13T12:00:00Z" } ] } ]}The parts that matter:
destination.wormImmutablerecords the immutability observed at write time. The manifest is signed, so this is a tamper-evident answer to “was this backup on WORM storage”.status(run and per-repo):success,failed, orskipped(resume found the repo already backed up for the date).repos[].errorappears only onfailed.artifacts[].kind:bundle,meta,sha256, orlfs.- Timestamps are RFC 3339 UTC. The signature is ed25519 over the exact stored bytes,
base64 in the
.sigsidecar.
--output json per command
Section titled “--output json per command”| Command | stdout shape |
|---|---|
backup |
the run-manifest above |
restore |
{ "bundleKey", "sha256", "outDir", "verified" } |
verify |
{ "manifestKey", "signatureValid", "artifactsChecked", "artifactsOk", "failures": [...] } |
doctor |
{ "ok", "checks": [ { "name", "ok", "detail" } ] } |
Logs stay on stderr, so gitdr backup --output json | jq .status just works.
Metadata dump (gitdr.meta/v1)
Section titled “Metadata dump (gitdr.meta/v1)”{repo}.meta.json holds raw upstream objects per section. GitHub: repo, labels,
milestones, issues, comments, pullRequests, reviewComments, releases. GitLab:
project, labels, milestones, issues, mergeRequests, releases, notes.
It’s an audit record, not a restorable snapshot. No tool can replay issues or PRs into a host with the original numbers, authors, and timestamps.