macula_rag_corpus (macula_rag v0.3.0)
View SourceThe RAG service contract's corpus identity: which corpus answered, and who vouches for it. Pure. guides/rag_service_contract.md is the canonical text, and test/vectors carries its frozen vectors.
CORPUS HASH. A provider describes its corpus as its embedding (model, dim) and its repos, each an id, url, branch and the pinned commit. corpus_hash is the lowercase hex sha256 of the RFC 8785 canonical JSON of {"dim", "model", "repos": [{"branch", "commit", "id", "url"}]}, repos in list order. The same repos in another embedding are another corpus.
THE OPERATOR'S SIGNATURE is optional. When present it is a macula_signed_object, carrying its key, over {corpus_hash} under the label signature_label/0. It is static: any provider can serve a copy. So a caller counts a corpus as signed by P only when it called P itself (macula:call/6 with #{provider => P}), and verify/3 is the whole check: the description hashes to what it claims, the object verifies under the label and the caller's profile, the node id derived from the VERIFIED key is P, and the signed hash is the recomputed one. signed_by in a description is a display label and never read here.
PROVENANCE. Every hit says where its text came from: kindcorpus (with repo_id and the 40-hex commit it was ingested at) or deposit, its path, and content_sha256, the sha256 of the text. verify_hit/1 checks the text against that hash; it says nothing about whether the provider told the truth about the repo, which is what the signed corpus is for.
Summary
Functions
RFC 8785 canonical JSON for what a corpus identity holds: objects with binary keys (sorted; ASCII keys, where UTF-16 code-unit order is byte order), arrays, strings and integers.
The corpus hash of a well-formed description, as a provider builds it. A received one goes through verify/3, which checks its shape first.
A provider's signature over its corpus hash, with its identity key: the encoded macula_signed_object, bytes on the wire.
The label a corpus signature is made under.
Whether a provenance has the contract's shape: corpus content names its repo and 40-hex commit, a deposit names neither; both name a path and the 64-hex sha256 of the text.
Check a description from the provider the caller pinned, under the caller's profile. {ok, unsigned} when it carries no signature.
ok when a hit's text is the text its provenance hashes.
Types
-type verdict() :: {ok, unsigned | {signed, <<_:256>>}} | {error, malformed_description | corpus_hash_mismatch | signer_not_provider | signature_hash_mismatch | {signature, term()}}.
Functions
RFC 8785 canonical JSON for what a corpus identity holds: objects with binary keys (sorted; ASCII keys, where UTF-16 code-unit order is byte order), arrays, strings and integers.
The corpus hash of a well-formed description, as a provider builds it. A received one goes through verify/3, which checks its shape first.
-spec sign(binary(), macula_node_keys:node_key()) -> binary().
A provider's signature over its corpus hash, with its identity key: the encoded macula_signed_object, bytes on the wire.
-spec signature_label() -> binary().
The label a corpus signature is made under.
Whether a provenance has the contract's shape: corpus content names its repo and 40-hex commit, a deposit names neither; both name a path and the 64-hex sha256 of the text.
-spec verify(map(), <<_:256>>, macula_crypto_profile:profile()) -> verdict().
Check a description from the provider the caller pinned, under the caller's profile. {ok, unsigned} when it carries no signature.
-spec verify_hit(map()) -> ok | {error, malformed_provenance | content_mismatch}.
ok when a hit's text is the text its provenance hashes.