Introduce repository-backed capability workspaces
- define and validate the capability and resource-lock languages - provision workspace source repositories through Central Gitea - build package runtimes from pinned standalone sources - replace legacy schema compilation with workspace persistence plans - add stable optimistic registers and Automerge CRDT documents - modernize TypeScript/Nix package builds and runtime activation readiness
This commit is contained in:
@@ -0,0 +1,373 @@
|
||||
declare const opaqueIdBrand: unique symbol;
|
||||
|
||||
type OpaqueId<Kind extends string> = string & {
|
||||
readonly [opaqueIdBrand]: Kind;
|
||||
};
|
||||
|
||||
export type WorkspaceId = OpaqueId<"WorkspaceId">;
|
||||
export type WorkspaceRevisionId = OpaqueId<"WorkspaceRevisionId">;
|
||||
export type AtomId = OpaqueId<"AtomId">;
|
||||
export type InterfaceId = OpaqueId<"InterfaceId">;
|
||||
export type InterfaceRevisionId = OpaqueId<"InterfaceRevisionId">;
|
||||
export type MemberId = OpaqueId<"MemberId">;
|
||||
export type OperationId = OpaqueId<"OperationId">;
|
||||
export type SlotId = OpaqueId<"SlotId">;
|
||||
export type EdgeTypeId = OpaqueId<"EdgeTypeId">;
|
||||
export type EdgeProjectionId = OpaqueId<"EdgeProjectionId">;
|
||||
export type PackageId = OpaqueId<"PackageId">;
|
||||
export type PackageRevisionId = OpaqueId<"PackageRevisionId">;
|
||||
export type PackageExportId = OpaqueId<"PackageExportId">;
|
||||
export type DependencyPortId = OpaqueId<"DependencyPortId">;
|
||||
export type ObjectId = OpaqueId<"ObjectId">;
|
||||
|
||||
const opaque = <Kind extends string>(value: string) => value as OpaqueId<Kind>;
|
||||
|
||||
/**
|
||||
* Textual IDs remain opaque to the semantic model. Authoring tools may mint
|
||||
* UUID-backed values later without changing the checked IR.
|
||||
*/
|
||||
export const capabilityId = {
|
||||
workspace: (value: string) => opaque<"WorkspaceId">(value),
|
||||
workspaceRevision: (value: string) =>
|
||||
opaque<"WorkspaceRevisionId">(value),
|
||||
atom: (value: string) => opaque<"AtomId">(value),
|
||||
interface: (value: string) => opaque<"InterfaceId">(value),
|
||||
interfaceRevision: (value: string) =>
|
||||
opaque<"InterfaceRevisionId">(value),
|
||||
member: (value: string) => opaque<"MemberId">(value),
|
||||
operation: (value: string) => opaque<"OperationId">(value),
|
||||
slot: (value: string) => opaque<"SlotId">(value),
|
||||
edgeType: (value: string) => opaque<"EdgeTypeId">(value),
|
||||
edgeProjection: (value: string) => opaque<"EdgeProjectionId">(value),
|
||||
package: (value: string) => opaque<"PackageId">(value),
|
||||
packageRevision: (value: string) => opaque<"PackageRevisionId">(value),
|
||||
packageExport: (value: string) => opaque<"PackageExportId">(value),
|
||||
dependencyPort: (value: string) => opaque<"DependencyPortId">(value),
|
||||
object: (value: string) => opaque<"ObjectId">(value),
|
||||
} as const;
|
||||
|
||||
export interface SourceRevision {
|
||||
repository: string;
|
||||
commit: string;
|
||||
}
|
||||
|
||||
export type ScalarValueTypeName =
|
||||
| "bool"
|
||||
| "bytes"
|
||||
| "double"
|
||||
| "int32"
|
||||
| "int64"
|
||||
| "string"
|
||||
| "uint32"
|
||||
| "uint64";
|
||||
|
||||
export type ObjectExpectation =
|
||||
| { kind: "atom"; atomId: AtomId }
|
||||
| {
|
||||
kind: "interface";
|
||||
interfaceRevisionId: InterfaceRevisionId;
|
||||
};
|
||||
|
||||
export type ValueType =
|
||||
| { kind: "builtin"; name: "unit" | "watch-handle" }
|
||||
| { kind: "scalar"; name: ScalarValueTypeName }
|
||||
| { kind: "message"; descriptorId: string }
|
||||
| { kind: "object-ref"; expectation: ObjectExpectation }
|
||||
| { kind: "optional"; value: ValueType }
|
||||
| { kind: "list"; value: ValueType };
|
||||
|
||||
export const valueType = {
|
||||
unit: { kind: "builtin", name: "unit" } as const,
|
||||
watchHandle: { kind: "builtin", name: "watch-handle" } as const,
|
||||
bool: { kind: "scalar", name: "bool" } as const,
|
||||
bytes: { kind: "scalar", name: "bytes" } as const,
|
||||
double: { kind: "scalar", name: "double" } as const,
|
||||
int32: { kind: "scalar", name: "int32" } as const,
|
||||
int64: { kind: "scalar", name: "int64" } as const,
|
||||
string: { kind: "scalar", name: "string" } as const,
|
||||
uint32: { kind: "scalar", name: "uint32" } as const,
|
||||
uint64: { kind: "scalar", name: "uint64" } as const,
|
||||
message: (descriptorId: string): ValueType => ({
|
||||
kind: "message",
|
||||
descriptorId,
|
||||
}),
|
||||
atomRef: (atomId: AtomId): ValueType => ({
|
||||
kind: "object-ref",
|
||||
expectation: { kind: "atom", atomId },
|
||||
}),
|
||||
interfaceRef: (interfaceRevisionId: InterfaceRevisionId): ValueType => ({
|
||||
kind: "object-ref",
|
||||
expectation: { kind: "interface", interfaceRevisionId },
|
||||
}),
|
||||
optional: (value: ValueType): ValueType => ({ kind: "optional", value }),
|
||||
list: (value: ValueType): ValueType => ({ kind: "list", value }),
|
||||
} as const;
|
||||
|
||||
export interface AtomDefinition {
|
||||
id: AtomId;
|
||||
displayName: string;
|
||||
documentation?: string;
|
||||
}
|
||||
|
||||
export type InterfaceOperationMode =
|
||||
| "call"
|
||||
| "watch-start"
|
||||
| "watch-stop"
|
||||
| "subscribe"
|
||||
| "unsubscribe";
|
||||
|
||||
export interface InterfaceOperation {
|
||||
id: OperationId;
|
||||
displayName: string;
|
||||
inputType: ValueType;
|
||||
outputType: ValueType;
|
||||
mode: InterfaceOperationMode;
|
||||
/** Required for watch-start/subscribe and absent for other modes. */
|
||||
eventType?: ValueType;
|
||||
}
|
||||
|
||||
interface InterfaceMemberBase {
|
||||
id: MemberId;
|
||||
displayName: string;
|
||||
operations: InterfaceOperation[];
|
||||
}
|
||||
|
||||
export interface ValueInterfaceMember extends InterfaceMemberBase {
|
||||
kind: "value";
|
||||
valueType: ValueType;
|
||||
}
|
||||
|
||||
export type EdgeCardinality =
|
||||
| "optional-one"
|
||||
| "exactly-one"
|
||||
| "many"
|
||||
| "many-unique";
|
||||
|
||||
export type EdgeEndpointConstraint =
|
||||
| { kind: "atom"; atomId: AtomId }
|
||||
| {
|
||||
kind: "interface";
|
||||
interfaceRevisionId: InterfaceRevisionId;
|
||||
};
|
||||
|
||||
export interface RelationshipInterfaceMember extends InterfaceMemberBase {
|
||||
kind: "relationship";
|
||||
target: EdgeEndpointConstraint;
|
||||
cardinality: EdgeCardinality;
|
||||
ordered: boolean;
|
||||
}
|
||||
|
||||
/** A named callable capability that is not value or relationship sugar. */
|
||||
export interface OperationInterfaceMember extends InterfaceMemberBase {
|
||||
kind: "operation";
|
||||
inputType: ValueType;
|
||||
outputType: ValueType;
|
||||
}
|
||||
|
||||
export type InterfaceMember =
|
||||
| ValueInterfaceMember
|
||||
| RelationshipInterfaceMember
|
||||
| OperationInterfaceMember;
|
||||
|
||||
export interface InterfaceRevision {
|
||||
interfaceId: InterfaceId;
|
||||
revisionId: InterfaceRevisionId;
|
||||
displayName: string;
|
||||
source: SourceRevision;
|
||||
members: InterfaceMember[];
|
||||
}
|
||||
|
||||
export type StoragePolicy =
|
||||
| { kind: "optimistic-register" }
|
||||
| { kind: "crdt-document"; updateType: ValueType };
|
||||
|
||||
export interface StateSlotDefinition {
|
||||
kind: "state";
|
||||
id: SlotId;
|
||||
attachedTo: AtomId;
|
||||
displayName: string;
|
||||
valueType: ValueType;
|
||||
storagePolicy: StoragePolicy;
|
||||
defaultValue?: unknown;
|
||||
}
|
||||
|
||||
export interface EdgeEndpoint {
|
||||
projectionId: EdgeProjectionId;
|
||||
displayName: string;
|
||||
constraint: EdgeEndpointConstraint;
|
||||
cardinality: EdgeCardinality;
|
||||
ordered: boolean;
|
||||
}
|
||||
|
||||
export interface EdgeDefinition {
|
||||
kind: "edge";
|
||||
id: EdgeTypeId;
|
||||
displayName: string;
|
||||
endpoints: [EdgeEndpoint, EdgeEndpoint];
|
||||
}
|
||||
|
||||
export type PersistentAttachment = StateSlotDefinition | EdgeDefinition;
|
||||
|
||||
export type StatePrimitive =
|
||||
| "read"
|
||||
| "write"
|
||||
| "watch-start"
|
||||
| "watch-stop";
|
||||
|
||||
export type EdgePrimitive =
|
||||
| "resolve"
|
||||
| "connect"
|
||||
| "disconnect"
|
||||
| "watch-start"
|
||||
| "watch-stop";
|
||||
|
||||
export type PackageReceiverRequirement =
|
||||
| { kind: "any-object" }
|
||||
| { kind: "exact-atom"; atomId: AtomId }
|
||||
| {
|
||||
kind: "all-interfaces";
|
||||
interfaceRevisionIds: InterfaceRevisionId[];
|
||||
};
|
||||
|
||||
export type DependencyPortRequirement =
|
||||
| {
|
||||
kind: "state";
|
||||
valueType: ValueType;
|
||||
primitives: StatePrimitive[];
|
||||
}
|
||||
| {
|
||||
kind: "edge";
|
||||
target: EdgeEndpointConstraint;
|
||||
cardinality: EdgeCardinality;
|
||||
primitives: EdgePrimitive[];
|
||||
}
|
||||
| {
|
||||
kind: "receiver-interface";
|
||||
interfaceRevisionId: InterfaceRevisionId;
|
||||
}
|
||||
| { kind: "constructor"; atomId: AtomId };
|
||||
|
||||
export interface DependencyPort {
|
||||
id: DependencyPortId;
|
||||
displayName: string;
|
||||
requirement: DependencyPortRequirement;
|
||||
}
|
||||
|
||||
interface PackageExportBase {
|
||||
id: PackageExportId;
|
||||
displayName: string;
|
||||
inputType: ValueType;
|
||||
outputType: ValueType;
|
||||
dependencyPorts: DependencyPort[];
|
||||
}
|
||||
|
||||
export interface PackageOperationExport extends PackageExportBase {
|
||||
kind: "operation";
|
||||
mode: InterfaceOperationMode;
|
||||
eventType?: ValueType;
|
||||
receiverRequirement: PackageReceiverRequirement;
|
||||
}
|
||||
|
||||
export interface PackageFunctionExport extends PackageExportBase {
|
||||
kind: "function";
|
||||
}
|
||||
|
||||
export interface PackageConstructorExport extends PackageExportBase {
|
||||
kind: "constructor";
|
||||
constructsAtom: AtomId;
|
||||
}
|
||||
|
||||
export type PackageExport =
|
||||
| PackageOperationExport
|
||||
| PackageFunctionExport
|
||||
| PackageConstructorExport;
|
||||
|
||||
export interface PackageRevision {
|
||||
packageId: PackageId;
|
||||
revisionId: PackageRevisionId;
|
||||
displayName: string;
|
||||
source: SourceRevision;
|
||||
exports: PackageExport[];
|
||||
}
|
||||
|
||||
export type DependencyBinding =
|
||||
| { kind: "state"; slotId: SlotId }
|
||||
| {
|
||||
kind: "edge";
|
||||
edgeTypeId: EdgeTypeId;
|
||||
projectionId: EdgeProjectionId;
|
||||
}
|
||||
| {
|
||||
kind: "receiver-interface";
|
||||
interfaceRevisionId: InterfaceRevisionId;
|
||||
}
|
||||
| { kind: "constructor"; atomId: AtomId };
|
||||
|
||||
export interface BoundDependency {
|
||||
portId: DependencyPortId;
|
||||
binding: DependencyBinding;
|
||||
}
|
||||
|
||||
export type Binding =
|
||||
| {
|
||||
kind: "state";
|
||||
slotId: SlotId;
|
||||
primitive: StatePrimitive;
|
||||
}
|
||||
| {
|
||||
kind: "edge";
|
||||
edgeTypeId: EdgeTypeId;
|
||||
projectionId: EdgeProjectionId;
|
||||
primitive: EdgePrimitive;
|
||||
}
|
||||
| {
|
||||
kind: "package";
|
||||
packageRevisionId: PackageRevisionId;
|
||||
exportId: PackageExportId;
|
||||
dependencies: BoundDependency[];
|
||||
};
|
||||
|
||||
export interface OperationBinding {
|
||||
operationId: OperationId;
|
||||
binding: Binding;
|
||||
}
|
||||
|
||||
export interface Conformance {
|
||||
atomId: AtomId;
|
||||
interfaceRevisionId: InterfaceRevisionId;
|
||||
privateAttachments: PersistentAttachment[];
|
||||
operationBindings: OperationBinding[];
|
||||
}
|
||||
|
||||
export interface AtomConstructorBinding {
|
||||
atomId: AtomId;
|
||||
packageRevisionId: PackageRevisionId;
|
||||
exportId: PackageExportId;
|
||||
dependencies: BoundDependency[];
|
||||
}
|
||||
|
||||
export interface WorkspaceRevision {
|
||||
id: WorkspaceRevisionId;
|
||||
workspaceId: WorkspaceId;
|
||||
parentRevisionIds: WorkspaceRevisionId[];
|
||||
sourceRootCommit: string;
|
||||
atoms: AtomDefinition[];
|
||||
sharedAttachments: PersistentAttachment[];
|
||||
interfaceImports: InterfaceRevision[];
|
||||
packageImports: PackageRevision[];
|
||||
conformances: Conformance[];
|
||||
constructors: AtomConstructorBinding[];
|
||||
}
|
||||
|
||||
export type AttachmentOwner =
|
||||
| { kind: "workspace" }
|
||||
| {
|
||||
kind: "conformance";
|
||||
atomId: AtomId;
|
||||
interfaceRevisionId: InterfaceRevisionId;
|
||||
};
|
||||
|
||||
export interface OwnedAttachment {
|
||||
attachment: PersistentAttachment;
|
||||
owner: AttachmentOwner;
|
||||
}
|
||||
Reference in New Issue
Block a user