Status: experimental C9-A contract
Issue: #597
Authority: evidence/state record only; no dispatch, verification, acceptance, integration, Git-push, or merge authority.
GitHub Actions runners are ephemeral. A no-server IDKMesh project therefore needs a compact record that can survive runner teardown and tell a later coordinator:
The machine-readable contract is
schemas/github-ledger-record-v0.1.schema.json. A representative synthetic
dispatch record is
examples/github-ledger/dispatch-record-v0.1.json.
C9-A freezes the record shape only. C9-B/C9-C own deterministic append serialization and optimistic/concurrent Git writes.
One ledger record is one immutable event observation. It contains:
The record does not contain mutable “current state” that overwrites earlier history. Later records describe later observations.
The route object deliberately preserves the recovery context requested by #601:
routing_digest;policy_version;The tier, authority, and risk vocabularies match
idkmesh.connector_routing v0.1.
This allows a killed coordinator to reconstruct not only what was selected but why.
Every record carries:
dispatch_key;request_digest;attempt_number.When an attempt object is present, its attempt_number must equal
idempotency.attempt_number. JSON Schema cannot express that cross-field
equality, so C9-B/C9-E writers and readers must enforce it.
The schema does not itself reserve or execute that key. C9-D must define atomic admission semantics so:
same dispatch_key + same request_digest -> existing logical run/attempt
same dispatch_key + different request_digest -> conflict
Actions concurrency may serialize work but is never the durable idempotency
source.
An attempt, when present, records:
Provider metadata is intentionally compact:
Provider tokens, auth headers, credentials, request payloads, prompts, and raw provider responses are outside the contract.
submission_state=ambiguous is preserved explicitly so recovery can avoid
blind resubmission when it is unknown whether a provider accepted the request.
CandidateReference, ResultManifest, VerificationResult, and Human Decision content are not embedded in the ledger record.
A retained reference contains only:
The evidence kind is bound to its slot: candidate_reference holds only a
candidate_reference, result_manifest only a result_manifest, every
verification_results item only a verification_result, and
human_decision.record only a human_decision_record. A recovery reader can
therefore trust the slot without re-deriving the kind.
Repository-relative paths are bounded and follow the same safe-path rules as the
C14-C durable evidence-link contract (idkmesh.github_evidence_link): no
leading or trailing /, no empty, . or .. segments, and no backslashes.
They are references to separately retained evidence; a digest/reference is not
a verdict.
A storage_path is not by itself a durable link. Presentation surfaces that
want a GitHub permalink must combine it with the repository and the exact
40/64-hex commit that retains the file, as required by
GitHub-First Operations §14.2; a moving
branch/tag link to the ledger branch is not durable evidence.
The ledger record intentionally does not use Actions artifacts/caches as a canonical evidence locator because those have finite retention. C9-H will define the retention policy.
Human decision state is explicit:
not_recorded;pending;recorded.When recorded, the ledger may carry the retained Human Decision Record digest
and repository-relative reference. A not_recorded or pending state must not
carry a record reference. It does not execute the decision or grant
integration authority.
Failure is a first-class optional object with:
Failed/cancelled/recovery-required observations remain append-only records. C9-B/C9-E must never reconstruct state by silently dropping negative events.
ledger_sequence and previous_record_digest prepare the contract for an
append-only chain:
ledger_sequence = 1) must use
previous_record_digest = null;The schema alone does not prove that a Git branch is append-only or that a previous digest exists. Those are storage/protocol properties for later slices.
The schema is closed at the top level and every nested object. It contains no fields for:
External provider identifiers are identifiers only. Implementations must not smuggle credentials into those strings.
A valid record structurally fixes every authority flag to false:
The record is evidence about an operation/state transition. It is never a credential or authorization to perform the next transition.
C9-A does not implement:
Those remain C9-B through C9-H.
This record is the C9 GitHub-native run/dispatch ledger. It is distinct from the Enterprise Audit Ledger v0.1, which records tamper-evident enterprise control-plane audit events in a local store. The two share the sequence + previous-digest chain idea but neither replaces the other: an enterprise audit event is not a dispatch/idempotency record, and a GitHub ledger record is not an enterprise audit event.
v0.1 is experimental but versioned. Once durable records are written under this schema, breaking semantic changes require a new schema version so historical ledger evidence remains interpretable.