Stand up mesh-sdk — the stable spine a module builds against
Per novox/hq ADR 0044/0045: the sdk holds only what rarely changes and is shared across modules; per-module code (a client, tool impls, a create-a-resource adapter) lives in the module. Five areas, real and tested: - contracts: the runtime shapes module code touches (grant, credential, a mesh Interface, tool + envelope types) — not the manifest schema, which the control plane owns. - provisioner: the reconcile harness every provider shares (watch grants, create via the module's adapter, seal + write the credential, remove on withdrawal). A module writes only the adapter. - tools: registerModuleTools + collectTools — the serving harness; tools and their client live in the module. - messaging: the Broker/Envelope/event contract over the mesh broker; the concrete binding is provided by the hosting runtime. - primitives: AES-256-GCM seal/unseal, semver, resolved-env access. Compiles (tsc, NodeNext) and passes tests: sealing round-trip + wrong-key rejection, semver, tool registration (a thrower is skipped not fatal), and the provisioner creating then removing a sealed grant. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
// The runtime shapes a module's own code touches — NOT the manifest schema, which the control
|
||||
// plane owns and parses (in Go). These are what a running module receives and returns: a grant
|
||||
// and its credentials, the mesh interface a provider and consumer both conform to, and the tool
|
||||
// and event types. They change rarely and deliberately (novox/hq ADR 0044).
|
||||
|
||||
/** A request for one instance of a provided resource, addressed to a provider. */
|
||||
export interface Grant {
|
||||
/** The mesh interface being provisioned, e.g. "analytics", "postgres-database". */
|
||||
readonly resource: string;
|
||||
/** Who asked — the consumer module, on which node. */
|
||||
readonly consumer: string;
|
||||
readonly node: string;
|
||||
/** What the consumer contributed (per the interface's spec keys), e.g. `{ name: "umami" }`. */
|
||||
readonly values: Readonly<Record<string, string>>;
|
||||
}
|
||||
|
||||
/** What a provider hands back for a grant. Sealed by the harness before it leaves the machine. */
|
||||
export interface Credential {
|
||||
/** The fields the interface promises a consumer, e.g. `{ host, port, as, password }`. */
|
||||
readonly fields: Readonly<Record<string, string>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A mesh interface: the provider-neutral contract for a capability (novox/hq ADR 0045). Both a
|
||||
* provider (which adapts its software to it) and a consumer (which depends on it, never on a
|
||||
* provider) conform. `spec` names what a consumer may contribute; `credential` names what it
|
||||
* receives. The interface is drawn at the consumer's real coupling: neutral where thin
|
||||
* (`analytics`), the protocol where the consumer speaks one (`postgres-database`).
|
||||
*/
|
||||
export interface Interface {
|
||||
readonly name: string;
|
||||
/** Keys a consumer may contribute when requesting it. */
|
||||
readonly spec: readonly string[];
|
||||
/** Fields a consumer receives in its credential. */
|
||||
readonly credential: readonly string[];
|
||||
}
|
||||
|
||||
/** A tool a module exposes through the mesh's command surface. */
|
||||
export interface ToolDefinition {
|
||||
readonly name: string;
|
||||
readonly description: string;
|
||||
/** JSON-schema-shaped input contract; kept opaque here so tools own their own shapes. */
|
||||
readonly input: Readonly<Record<string, unknown>>;
|
||||
readonly run: (args: Readonly<Record<string, unknown>>) => Promise<unknown>;
|
||||
}
|
||||
|
||||
/** A message crossing the broker: a routing key and a JSON body, per-node addressed. */
|
||||
export interface Envelope<T = unknown> {
|
||||
readonly key: string;
|
||||
readonly node: string;
|
||||
readonly body: T;
|
||||
}
|
||||
Reference in New Issue
Block a user