Skip to main content

Module catalogue

Module catalogue 

Source
Expand description

The advisor catalogue: share/advisors.yaml, one declaration of every advisory role a session may consult, in the grain of share/providers.yaml and share/models.yaml.

An advisor is not a provider and not a vendor. A provider is a client tool that works in this repository (ADR 0024); a vendor serves models (ADR 0049); an advisor is a role — something a session may ask for an independent opinion — reached through one transport. The catalogue therefore holds only what neither neighbour knows: the transport, the adapter that speaks it, the executable whose presence says it is installed, and the advisory capabilities it offers. Everything else is a reference — a provider id, a vendor id, a model id — and AdvisorCatalogue::diagnostics refuses a reference that resolves to nothing, so the three tables cannot fork.

Declaration order is the preference order. That is where a repository’s “ask this one first” lives: as data the policy reads, never as a name the policy knows.

§Example

A share directory declaring two advisors and the vendor one of them references: load, resolve the references, check the catalogue, then look an advisor up.

use majordomus_cli::reasoning::catalogue::{AdvisorCatalogue, ADVISORS_FILE};
use majordomus_cli::share::ProviderDeclarations;

let share = tempfile::tempdir().unwrap();
std::fs::write(share.path().join(ADVISORS_FILE), "version: 1\ncapabilities:\n  - id: code_review\n    description: x\nadvisors:\n  - id: a\n    title: A\n    transport: api\n    adapter: a-api\n    vendor: acme\n    capabilities: [code_review]\n  - id: b\n    title: B\n    transport: cli\n    adapter: b-cli\n    executable: b\n    capabilities: [code_review]\n").unwrap();
std::fs::write(share.path().join("models.yaml"), "version: 1\nvendors:\n  - id: acme\n    title: Acme\n    credential_env: ACME_KEY\nmodels: []\n").unwrap();

let catalogue = AdvisorCatalogue::load(share.path()).unwrap();
let refs = AdvisorCatalogue::references(share.path(), &ProviderDeclarations::default());
assert!(catalogue.diagnostics(&refs).is_empty());

let ids: Vec<&str> = catalogue.advisors.iter().map(|a| a.id.as_str()).collect();
assert_eq!(ids, ["a", "b"], "declaration order is preference order");
let a = catalogue.get("a").unwrap();
assert_eq!(catalogue.credential_of(a, &refs), Some("ACME_KEY"));

Structs§

AdvisorCatalogue
The whole catalogue, as share/advisors.yaml declares it: the capability vocabulary, the advisors in preference order, how mesh peers become advisors, and the claims no document may assert. The default is the empty catalogue a share without the file has.
AdvisorDeclaration
One declared advisor: its id, how it is reached and through which adapter, what it references in the provider and model tables, the executable that says it is installed, and the advisory capabilities it offers.
AdvisoryCapability
One advisory capability word of the declared vocabulary: what a plan requests and an advisor offers. A word outside the vocabulary is a catalogue finding.
PeerAdvisors
How linked mesh runtimes become advisors: those carrying feature, with these capabilities, through this adapter.
References
The names the catalogue’s references must resolve against: the provider ids of share/providers.yaml and the model catalogue of share/models.yaml.

Enums§

AdvisorTransport
How an advisor is reached. The transport decides how its presence is probed (a credential variable, an executable, a mesh link) and whether offline mode admits it.

Constants§

ADVISORS_FILE
The file name under the share directory.