81 lines
3.6 KiB
TypeScript
81 lines
3.6 KiB
TypeScript
// 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 0039).
|
|
|
|
/** 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 0040). 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>;
|
|
}
|
|
|
|
/**
|
|
* The metadata that rides an event as AMQP headers (novox/hq ADR 0042). An event's identity and
|
|
* provenance live here, not in the body, so a consumer — or the broker, or an audit tool — reads
|
|
* who/when/what without parsing the payload. An unknown `x-` header is ignored, not refused: an
|
|
* event is observed by parties that need not all understand every header.
|
|
*/
|
|
export interface EventHeaders {
|
|
/** A unique id — for dedup and audit (delivery is at-least-once). */
|
|
readonly "x-event-id": string;
|
|
/** The emitter: the module, context or node name. */
|
|
readonly "x-source": string;
|
|
/** The node it was emitted from. */
|
|
readonly "x-node": string;
|
|
/** Emit time, RFC-3339. */
|
|
readonly "x-time": string;
|
|
/** Always `application/json`. */
|
|
readonly "content-type": string;
|
|
/** The event or command that caused this one — tracing. */
|
|
readonly "x-causation-id"?: string;
|
|
/** A version of the body's shape, so a body evolves without silent misreads. */
|
|
readonly "x-schema"?: string;
|
|
readonly [header: string]: string | undefined;
|
|
}
|
|
|
|
/**
|
|
* A message crossing the broker: a routing key and a JSON body, per-node addressed. For an event,
|
|
* `headers` carries the ADR 0042 metadata; plain request/reply transport leaves it absent.
|
|
*/
|
|
export interface Envelope<T = unknown> {
|
|
readonly key: string;
|
|
readonly node: string;
|
|
readonly body: T;
|
|
readonly headers?: EventHeaders;
|
|
}
|