@githolon/dsl 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE.md +36 -0
  2. package/compile_package.mjs +50 -0
  3. package/package.json +59 -0
  4. package/src/aggregate.ts +167 -0
  5. package/src/authoring.ts +119 -0
  6. package/src/build_package.ts +636 -0
  7. package/src/certified_read.ts +313 -0
  8. package/src/codegen_dart.ts +2732 -0
  9. package/src/codegen_dot.ts +466 -0
  10. package/src/codegen_provider_dart.ts +358 -0
  11. package/src/codegen_ts.ts +365 -0
  12. package/src/codegen_usda.ts +388 -0
  13. package/src/combined.ts +195 -0
  14. package/src/compile_engine.ts +567 -0
  15. package/src/compile_package_main.ts +496 -0
  16. package/src/compose.ts +317 -0
  17. package/src/count.ts +218 -0
  18. package/src/ctx.ts +57 -0
  19. package/src/derived.ts +138 -0
  20. package/src/directive.ts +306 -0
  21. package/src/drivers.ts +95 -0
  22. package/src/emits_guard.ts +123 -0
  23. package/src/engine_entry.ts +449 -0
  24. package/src/exists.ts +170 -0
  25. package/src/extremum.ts +227 -0
  26. package/src/fields.ts +291 -0
  27. package/src/framework/bootstrap.ts +22 -0
  28. package/src/framework/disclosure.ts +108 -0
  29. package/src/framework/domain_lifecycle.ts +108 -0
  30. package/src/framework/identity.ts +537 -0
  31. package/src/framework/impure_capability.ts +643 -0
  32. package/src/framework/rbac.ts +418 -0
  33. package/src/framework/repair.ts +150 -0
  34. package/src/framework/sync_lifecycle.ts +125 -0
  35. package/src/framework/workspace_invariant.ts +128 -0
  36. package/src/framework/workspaces.ts +817 -0
  37. package/src/index.ts +317 -0
  38. package/src/manifest.ts +947 -0
  39. package/src/ops.ts +145 -0
  40. package/src/ordered_read.ts +228 -0
  41. package/src/predicate.ts +203 -0
  42. package/src/query/compile.ts +0 -0
  43. package/src/query/relations.ts +144 -0
  44. package/src/query.ts +151 -0
  45. package/src/read.ts +54 -0
  46. package/src/relation.ts +189 -0
  47. package/src/report/csv.ts +54 -0
  48. package/src/report.ts +401 -0
  49. package/src/spatial.ts +115 -0
  50. package/src/sum.ts +194 -0
  51. package/src/usd.ts +563 -0
  52. package/src/wire.ts +149 -0
  53. package/src/wire_encode.ts +250 -0
@@ -0,0 +1,125 @@
1
+ // NOMOS — Nomos Sovereign: participants act · verify · remember LOCALLY; hosted
2
+ // remotes are replaceable custody/transport, not truth. ⇒ ONE Nomos GitHolon
3
+ // wasm32-wasip1 artifact {kernel · projection · embedded
4
+ // QuickJS engine}. Host JS only instantiates the WASI module and supplies storage/transport;
5
+ // the wasm blob is the deterministic execution boundary. No native, no wasmtime,
6
+ // no 2nd artifact, no domain-JS on host V8.
7
+ // If a file isn't this / hosting this / authoring for this / proving this — it's gone.
8
+
9
+ /**
10
+ * Nomos sync lifecycle.
11
+ *
12
+ * Sync is a control-plane impure capability: Nomos records the desired workspace
13
+ * reconciliation as an ordinary Order, a host/provider performs transport using
14
+ * explicit capabilities, and the outcome comes back as an ordinary Receipt. The
15
+ * remote/JWT/network is never ambient domain state; the ledger carries request,
16
+ * status, cursors, heads, and errors.
17
+ */
18
+ import { z } from "zod";
19
+ import { instance, type BoundAggregate } from "../aggregate.js";
20
+ import { Lww } from "../drivers.js";
21
+ import { t } from "../fields.js";
22
+ import { set, type PlannedOp } from "../ops.js";
23
+ import {
24
+ impureCapability,
25
+ impureCapabilityAggregate,
26
+ type ImpureCapability,
27
+ } from "./impure_capability.js";
28
+
29
+ export const WORKSPACE_SYNC_DIRECTIONS = ["pull", "push", "pushPull"] as const;
30
+ export type WorkspaceSyncDirection = (typeof WORKSPACE_SYNC_DIRECTIONS)[number];
31
+
32
+ const syncParams = {
33
+ workspaceId: t.string().merge(Lww),
34
+ branch: t.string().merge(Lww),
35
+ remote: t.string().merge(Lww),
36
+ direction: t.enum(WORKSPACE_SYNC_DIRECTIONS).merge(Lww),
37
+ reason: t.string().merge(Lww).optional(),
38
+ authSessionRef: t.string().merge(Lww).optional(),
39
+ sinceCursor: t.string().merge(Lww).optional(),
40
+ resultHead: t.string().merge(Lww).optional(),
41
+ resultCursor: t.string().merge(Lww).optional(),
42
+ appliedIntentCount: t.int().merge(Lww).optional(),
43
+ pushedIntentCount: t.int().merge(Lww).optional(),
44
+ };
45
+
46
+ export const WorkspaceSyncOperation = impureCapabilityAggregate(
47
+ "WorkspaceSyncOperation",
48
+ syncParams,
49
+ );
50
+
51
+ function optionalParamOps(
52
+ sync: BoundAggregate<typeof WorkspaceSyncOperation.id, typeof syncParams>,
53
+ p: {
54
+ reason?: string | undefined;
55
+ authSessionRef?: string | undefined;
56
+ sinceCursor?: string | undefined;
57
+ },
58
+ ): PlannedOp[] {
59
+ const ops: PlannedOp[] = [];
60
+ if (p.reason !== undefined) ops.push(set(sync, "reason", p.reason));
61
+ if (p.authSessionRef !== undefined) ops.push(set(sync, "authSessionRef", p.authSessionRef));
62
+ if (p.sinceCursor !== undefined) ops.push(set(sync, "sinceCursor", p.sinceCursor));
63
+ return ops;
64
+ }
65
+
66
+ function syncResultOps(taskId: string, resultRef: string): PlannedOp[] {
67
+ const sync = instance(WorkspaceSyncOperation, taskId);
68
+ const ops: PlannedOp[] = [];
69
+ const result = JSON.parse(resultRef) as {
70
+ head?: unknown;
71
+ cursor?: unknown;
72
+ appliedIntentCount?: unknown;
73
+ pushedIntentCount?: unknown;
74
+ };
75
+ if (typeof result.head === "string") ops.push(set(sync, "resultHead", result.head));
76
+ if (typeof result.cursor === "string") ops.push(set(sync, "resultCursor", result.cursor));
77
+ if (Number.isInteger(result.appliedIntentCount)) {
78
+ ops.push(set(sync, "appliedIntentCount", result.appliedIntentCount as number));
79
+ }
80
+ if (Number.isInteger(result.pushedIntentCount)) {
81
+ ops.push(set(sync, "pushedIntentCount", result.pushedIntentCount as number));
82
+ }
83
+ return ops;
84
+ }
85
+
86
+ const workspaceSyncTask = impureCapability({
87
+ aggregateId: "WorkspaceSyncOperation",
88
+ orderDirectiveId: "requestWorkspaceSync",
89
+ completeDirectiveId: "completeWorkspaceSync",
90
+ failDirectiveId: "failWorkspaceSync",
91
+ blockDirectiveId: "blockWorkspaceSync",
92
+ deadLetterDirectiveId: "deadLetterWorkspaceSync",
93
+ params: syncParams,
94
+ paramsSchema: {
95
+ workspaceId: z.string(),
96
+ branch: z.string().default("main"),
97
+ remote: z.string(),
98
+ direction: z.enum(WORKSPACE_SYNC_DIRECTIONS).default("pull"),
99
+ reason: z.string().optional(),
100
+ authSessionRef: z.string().optional(),
101
+ sinceCursor: z.string().optional(),
102
+ },
103
+ writeParams: (taskId, p) => {
104
+ const sync = instance(WorkspaceSyncOperation, taskId);
105
+ return [
106
+ set(sync, "workspaceId", p.workspaceId),
107
+ set(sync, "branch", p.branch),
108
+ set(sync, "remote", p.remote),
109
+ set(sync, "direction", p.direction),
110
+ ...optionalParamOps(sync, p),
111
+ ];
112
+ },
113
+ completeResult: syncResultOps,
114
+ });
115
+
116
+ export const requestWorkspaceSync = workspaceSyncTask.order.requires("requestWorkspaceSync");
117
+ export const completeWorkspaceSync = workspaceSyncTask.complete.requires("completeWorkspaceSync");
118
+ export const failWorkspaceSync = workspaceSyncTask.fail.requires("failWorkspaceSync");
119
+ export const blockWorkspaceSync = workspaceSyncTask.block.requires("blockWorkspaceSync");
120
+ export const deadLetterWorkspaceSync =
121
+ workspaceSyncTask.deadLetter.requires("deadLetterWorkspaceSync");
122
+
123
+ export const NOMOS_SYNC_IMPURE_CAPABILITIES: ImpureCapability<string, never, never>[] = [
124
+ workspaceSyncTask as unknown as ImpureCapability<string, never, never>,
125
+ ];
@@ -0,0 +1,128 @@
1
+ // NOMOS — Nomos Sovereign: participants act · verify · remember LOCALLY; hosted
2
+ // remotes are replaceable custody/transport, not truth. ⇒ ONE Nomos GitHolon
3
+ // wasm32-wasip1 artifact {kernel · projection · embedded
4
+ // QuickJS engine} on V8 + WASI-shim, byte-identical everywhere. V8 = portability; the one
5
+ // wasm = determinism. No native, no wasmtime, no 2nd artifact, no domain-JS on bare V8.
6
+ // If a file isn't this / hosting this / authoring for this / proving this — it's gone.
7
+
8
+ /**
9
+ * framework/workspace_invariant — the WORKSPACE INVARIANT authoring surface (#266).
10
+ *
11
+ * Consistency level 2 of 3 (see `docs/workspace_invariant.md`): a HARD, synchronous,
12
+ * admission-time predicate over a BOUNDED, DECLARED set of POST-APPLY aggregate snapshots —
13
+ * possibly ACROSS DOMAINS within the ONE workspace. (Level 1 = the per-aggregate `invariant`
14
+ * (#250); level 3 = cross-workspace carried evidence, never a synchronous invariant.)
15
+ *
16
+ * workspaceInvariant("ItemMustReferenceActiveRevision")
17
+ * .on("inventory.MoveItem") // fires for this directive
18
+ * .reads(({ intent }) => [ // BOUNDED, DECLARED read-set
19
+ * ref("inventory.Item", intent.item as string), // (refs, possibly cross-domain,
20
+ * ref("layout.Revision", intent.revision as string),// within THIS workspace)
21
+ * ])
22
+ * .assert(({ item, revision }) => // post-apply predicate, PURE
23
+ * (revision as any).status === "active" &&
24
+ * (item as any).zone === (revision as any).zone
25
+ * ? { accept: true }
26
+ * : { reject: "item-must-reference-active-revision" });
27
+ *
28
+ * MUST be explicit · bounded · declared · deterministic · versioned · replayable. The body
29
+ * runs in the SEALED engine over the resolved named-map snapshots (the engine half is
30
+ * `plan_workspace_invariant`, #266 slice 1); the read-set is RECORDED as validation-deps at
31
+ * admission (slice 4). PRESENCE ONLY is hashed in the manifest (id + the directive it is `on`),
32
+ * exactly like a directive `plan` / the aggregate `hasInvariant` — the executable bodies ship
33
+ * in the engine bundle, NEVER in the ledger. Changing a body does NOT move the domain hash;
34
+ * adding/removing an invariant DOES (it is law). NO arbitrary SQL / unbounded graph / whole-
35
+ * workspace scan / projection read / ambient "current world" read — only the declared refs.
36
+ */
37
+
38
+ /** A TYPED verdict — identical shape to the aggregate invariant (the engine parses both). */
39
+ export type WorkspaceInvariantVerdict = { accept: true } | { reject: string };
40
+
41
+ /**
42
+ * One DECLARED read: the aggregate TYPE (qualified `domain.Aggregate`) + the concrete instance
43
+ * id, derived from the intent. `name` is the binding key the `.assert` predicate destructures
44
+ * the resolved snapshot under — derived from the type's short segment (e.g. `inventory.Item`
45
+ * → `item`, `layout.Revision` → `revision`). For two refs of the same type, pass an explicit
46
+ * `name` via [`refAs`] to disambiguate.
47
+ */
48
+ export interface InvariantRef {
49
+ readonly name: string;
50
+ readonly aggregate: string;
51
+ readonly id: string;
52
+ }
53
+
54
+ /** `inventory.Item` → `item`; `layout.FloorPlan` → `floorPlan` (short segment, first-lower). */
55
+ function deriveName(aggregateType: string): string {
56
+ const short = aggregateType.includes(".")
57
+ ? aggregateType.slice(aggregateType.lastIndexOf(".") + 1)
58
+ : aggregateType;
59
+ return short.length > 0 ? short[0]!.toLowerCase() + short.slice(1) : short;
60
+ }
61
+
62
+ /** A declared read of `aggregateType`'s instance `id`; bound under its derived short name. */
63
+ export function ref(aggregateType: string, id: string): InvariantRef {
64
+ return { name: deriveName(aggregateType), aggregate: aggregateType, id };
65
+ }
66
+
67
+ /** A declared read bound under an EXPLICIT `name` (disambiguates two refs of the same type). */
68
+ export function refAs(name: string, aggregateType: string, id: string): InvariantRef {
69
+ return { name, aggregate: aggregateType, id };
70
+ }
71
+
72
+ /** Derive the BOUNDED declared read-set from the intent payload. Pure — no IO, no live read. */
73
+ export type WorkspaceInvariantReads = (ctx: { intent: Record<string, unknown> }) => InvariantRef[];
74
+
75
+ /**
76
+ * The post-apply predicate over the resolved snapshots, keyed by each ref's binding `name`.
77
+ * PURE over the named map (no clock, no IO, no live reads) — runs in the sealed engine.
78
+ */
79
+ export type WorkspaceInvariantAssert = (
80
+ snapshots: Record<string, Record<string, unknown>>,
81
+ ) => WorkspaceInvariantVerdict;
82
+
83
+ /** A complete, registered workspace-invariant declaration (the `.assert` terminal yields this). */
84
+ export interface WorkspaceInvariantDecl {
85
+ /** The stable wire id — the literal passed to `workspaceInvariant(...)`. Hashed (presence). */
86
+ readonly id: string;
87
+ /** The directive id this invariant fires on (e.g. `inventory.MoveItem`). Hashed (presence). */
88
+ readonly on: string;
89
+ /** The executable declared read-set — ships in the engine bundle, NOT the manifest. */
90
+ readonly reads: WorkspaceInvariantReads;
91
+ /** The executable predicate — ships in the engine bundle, NOT the manifest. */
92
+ readonly assert: WorkspaceInvariantAssert;
93
+ /** Brand so a plain object is never mistaken for a declaration. */
94
+ readonly __isWorkspaceInvariant: true;
95
+ }
96
+
97
+ /**
98
+ * Author a workspace invariant: `workspaceInvariant(id).on(directive).reads(fn).assert(fn)`.
99
+ * The staged builder makes every step REQUIRED at the type level — you cannot register a
100
+ * half-declared invariant (no `.on`, no `.reads`, or no `.assert`).
101
+ */
102
+ export function workspaceInvariant(id: string): {
103
+ on(directiveId: string): {
104
+ reads(reads: WorkspaceInvariantReads): {
105
+ assert(assert: WorkspaceInvariantAssert): WorkspaceInvariantDecl;
106
+ };
107
+ };
108
+ } {
109
+ return {
110
+ on(directiveId: string) {
111
+ return {
112
+ reads(reads: WorkspaceInvariantReads) {
113
+ return {
114
+ assert(assert: WorkspaceInvariantAssert): WorkspaceInvariantDecl {
115
+ return {
116
+ id,
117
+ on: directiveId,
118
+ reads,
119
+ assert,
120
+ __isWorkspaceInvariant: true,
121
+ };
122
+ },
123
+ };
124
+ },
125
+ };
126
+ },
127
+ };
128
+ }