@dynamicalsystems/idl 0.7.0 → 0.8.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.
@@ -0,0 +1,127 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/DynamicalSystemsGroup/dsg-idl/schema/dsg-run-run-summary-v1.json",
4
+ "title": "dsg.run.run-summary/1",
5
+ "$defs": {
6
+ "summary": {
7
+ "additionalProperties": false,
8
+ "type": "object",
9
+ "required": ["profile", "runId", "experimentDigest", "requester", "decision", "waitingOn"],
10
+ "properties": {
11
+ "profile": {
12
+ "const": "dsg.run.run-summary/1",
13
+ "type": "string"
14
+ },
15
+ "runId": {
16
+ "minLength": 1,
17
+ "type": "string"
18
+ },
19
+ "experimentDigest": {
20
+ "pattern": "^[0-9a-f]{64}$",
21
+ "type": "string"
22
+ },
23
+ "requester": {
24
+ "anyOf": [
25
+ {
26
+ "additionalProperties": false,
27
+ "type": "object",
28
+ "required": ["principal", "displayName", "source"],
29
+ "properties": {
30
+ "principal": {
31
+ "pattern": "^orn:[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*){3}:(?:[A-Za-z0-9\\-._~:/@]|%[0-9A-Fa-f]{2})+$",
32
+ "type": "string"
33
+ },
34
+ "displayName": {
35
+ "minLength": 1,
36
+ "type": "string"
37
+ },
38
+ "source": {
39
+ "minLength": 1,
40
+ "type": "string"
41
+ }
42
+ }
43
+ },
44
+ {
45
+ "type": "null"
46
+ }
47
+ ]
48
+ },
49
+ "decision": {
50
+ "anyOf": [
51
+ {
52
+ "additionalProperties": false,
53
+ "type": "object",
54
+ "required": ["outcome", "decider", "decidedAt", "cause", "byStandingOrder"],
55
+ "properties": {
56
+ "outcome": {
57
+ "anyOf": [
58
+ {
59
+ "const": "approved",
60
+ "type": "string"
61
+ },
62
+ {
63
+ "const": "refused",
64
+ "type": "string"
65
+ }
66
+ ]
67
+ },
68
+ "decider": {
69
+ "additionalProperties": false,
70
+ "type": "object",
71
+ "required": ["principal", "displayName", "source"],
72
+ "properties": {
73
+ "principal": {
74
+ "pattern": "^orn:[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*){3}:(?:[A-Za-z0-9\\-._~:/@]|%[0-9A-Fa-f]{2})+$",
75
+ "type": "string"
76
+ },
77
+ "displayName": {
78
+ "minLength": 1,
79
+ "type": "string"
80
+ },
81
+ "source": {
82
+ "minLength": 1,
83
+ "type": "string"
84
+ }
85
+ }
86
+ },
87
+ "decidedAt": {
88
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$",
89
+ "type": "string"
90
+ },
91
+ "cause": {
92
+ "anyOf": [
93
+ {
94
+ "minLength": 1,
95
+ "type": "string"
96
+ },
97
+ {
98
+ "type": "null"
99
+ }
100
+ ]
101
+ },
102
+ "byStandingOrder": {
103
+ "type": "boolean"
104
+ }
105
+ }
106
+ },
107
+ {
108
+ "type": "null"
109
+ }
110
+ ]
111
+ },
112
+ "waitingOn": {
113
+ "anyOf": [
114
+ {
115
+ "minLength": 1,
116
+ "type": "string"
117
+ },
118
+ {
119
+ "type": "null"
120
+ }
121
+ ]
122
+ }
123
+ }
124
+ }
125
+ },
126
+ "$ref": "#/$defs/summary"
127
+ }
@@ -0,0 +1,26 @@
1
+ // dsg.core.identity-binding/1
2
+ // Owner: dsg-kernel. A binding is a signed act through the door.
3
+ // The CLI signs; the plane forwards; the kernel verifies and appends.
4
+ import { type Static, Type } from "@sinclair/typebox";
5
+ import { closed, NonEmptyString, Orn, UtcSecond, type ProfileEntry } from "../primitives.js";
6
+
7
+ export const IDENTITY_BINDING_PROFILE = "dsg.core.identity-binding/1" as const;
8
+ export const GOOGLE_SIGN_IN_ISSUER = "https://accounts.google.com" as const;
9
+
10
+ const IdentityBindingSchemaValue = closed({
11
+ profile: Type.Literal(IDENTITY_BINDING_PROFILE),
12
+ principal: Orn,
13
+ issuer: Type.Literal(GOOGLE_SIGN_IN_ISSUER),
14
+ subject: NonEmptyString,
15
+ decider: Orn,
16
+ boundAt: UtcSecond,
17
+ signature: NonEmptyString,
18
+ });
19
+ export const IdentityBindingSchema: typeof IdentityBindingSchemaValue = IdentityBindingSchemaValue;
20
+ export type IdentityBinding = Static<typeof IdentityBindingSchema>;
21
+
22
+ export const identityBindingV1: ProfileEntry = {
23
+ literal: IDENTITY_BINDING_PROFILE,
24
+ rootShape: "binding",
25
+ shapes: { binding: IdentityBindingSchema },
26
+ };
@@ -0,0 +1,45 @@
1
+ // dsg.core.refusal/1
2
+ // Owner: shared. Kernel, plane, and console read this one envelope.
3
+ // Identity ladder codes are identity-verifier-spec.md section 3.5.
4
+ // Login and request codes are person-loop-spec.md sections 4.1 and 4.2.
5
+ // The sentence is what a person hears; identifiers do not belong here.
6
+ import { type Static, Type } from "@sinclair/typebox";
7
+ import { closed, NonEmptyString, type ProfileEntry } from "../primitives.js";
8
+
9
+ export const REFUSAL_PROFILE = "dsg.core.refusal/1" as const;
10
+
11
+ const RefusalCodeSchemaValue = Type.Union([
12
+ Type.Literal("assertion_invalid"),
13
+ Type.Literal("audience_mismatch"),
14
+ Type.Literal("expired"),
15
+ Type.Literal("issuer_unknown"),
16
+ Type.Literal("transport_unverified"),
17
+ Type.Literal("relay_untrusted"),
18
+ Type.Literal("identity_unbound"),
19
+ Type.Literal("binding_expired"),
20
+ Type.Literal("principal_suspended"),
21
+ Type.Literal("not_dsg_account"),
22
+ Type.Literal("session_expired"),
23
+ Type.Literal("unknown_workload_class"),
24
+ Type.Literal("image_not_pinned"),
25
+ Type.Literal("not_a_requester"),
26
+ Type.Literal("document_invalid"),
27
+ Type.Literal("self_decision"),
28
+ Type.Literal("no_ceiling"),
29
+ ]);
30
+ export const RefusalCodeSchema: typeof RefusalCodeSchemaValue = RefusalCodeSchemaValue;
31
+ export type RefusalCode = Static<typeof RefusalCodeSchema>;
32
+
33
+ const RefusalSchemaValue = closed({
34
+ profile: Type.Literal(REFUSAL_PROFILE),
35
+ code: RefusalCodeSchema,
36
+ sentence: NonEmptyString,
37
+ });
38
+ export const RefusalSchema: typeof RefusalSchemaValue = RefusalSchemaValue;
39
+ export type Refusal = Static<typeof RefusalSchema>;
40
+
41
+ export const refusalV1: ProfileEntry = {
42
+ literal: REFUSAL_PROFILE,
43
+ rootShape: "refusal",
44
+ shapes: { refusal: RefusalSchema },
45
+ };
package/src/index.ts CHANGED
@@ -1,4 +1,13 @@
1
- export { closed, Hex64, NonEmptyString, Orn, Reference, SafeInt, UtcSecond } from "./primitives.js";
1
+ export {
2
+ closed,
3
+ Hex64,
4
+ NonEmptyString,
5
+ Orn,
6
+ PersonReference,
7
+ Reference,
8
+ SafeInt,
9
+ UtcSecond,
10
+ } from "./primitives.js";
2
11
  export type { ProfileEntry } from "./primitives.js";
3
12
  export {
4
13
  DISPATCH_CONSUME_PROFILE,
@@ -76,6 +85,20 @@ export type {
76
85
  BootstrapIntent,
77
86
  SignedBootstrapIntent,
78
87
  } from "./kernel/bootstrap.v1.js";
88
+ export {
89
+ STANDING_ORDER_ACTIVATION_EVENT_KIND,
90
+ STANDING_ORDER_ACTIVATION_PROFILE,
91
+ StandingOrderActivationEventSchema,
92
+ StandingOrderActivationSchema,
93
+ StandingOrderModeSchema,
94
+ SignedStandingOrderActivationSchema,
95
+ } from "./kernel/standing-order-activation.v1.js";
96
+ export type {
97
+ StandingOrderActivation,
98
+ StandingOrderActivationEvent,
99
+ StandingOrderMode,
100
+ SignedStandingOrderActivation,
101
+ } from "./kernel/standing-order-activation.v1.js";
79
102
  export {
80
103
  ORDINARY_AUTHORITY_PROFILE,
81
104
  OrdinaryAuthoritySchema,
@@ -91,17 +114,46 @@ export {
91
114
  EventStreamSealSchema,
92
115
  } from "./run/event.v1.js";
93
116
  export type { Event, EventStreamSeal } from "./run/event.v1.js";
117
+ export {
118
+ REQUEST_PROFILE,
119
+ ExperimentRefSchema,
120
+ RequestCeilingsSchema,
121
+ RunRequestSchema,
122
+ } from "./run/request.v1.js";
123
+ export type { ExperimentRef, RequestCeilings, RunRequest } from "./run/request.v1.js";
124
+ export { DECISION_PROFILE, RunDecisionSchema } from "./run/decision.v1.js";
125
+ export type { RunDecision } from "./run/decision.v1.js";
126
+ export {
127
+ RUN_SUMMARY_PROFILE,
128
+ RunSummaryDecisionSchema,
129
+ RunSummarySchema,
130
+ } from "./run/run-summary.v1.js";
131
+ export type { RunSummary, RunSummaryDecision } from "./run/run-summary.v1.js";
132
+ export { REFUSAL_PROFILE, RefusalCodeSchema, RefusalSchema } from "./core/refusal.v1.js";
133
+ export type { Refusal, RefusalCode } from "./core/refusal.v1.js";
134
+ export {
135
+ GOOGLE_SIGN_IN_ISSUER,
136
+ IDENTITY_BINDING_PROFILE,
137
+ IdentityBindingSchema,
138
+ } from "./core/identity-binding.v1.js";
139
+ export type { IdentityBinding } from "./core/identity-binding.v1.js";
94
140
 
95
141
  import type { ProfileEntry } from "./primitives.js";
96
142
  import { dispatchConsumeV1 } from "./kernel/dispatch-consume.v1.js";
97
143
  import { operationV1 } from "./run/operation.v1.js";
98
144
  import { eventV1 } from "./run/event.v1.js";
145
+ import { requestV1 } from "./run/request.v1.js";
146
+ import { decisionV1 } from "./run/decision.v1.js";
147
+ import { runSummaryV1 } from "./run/run-summary.v1.js";
148
+ import { refusalV1 } from "./core/refusal.v1.js";
149
+ import { identityBindingV1 } from "./core/identity-binding.v1.js";
99
150
  import { signedLawV1 } from "./infra/signed-law.v1.js";
100
151
  import { resourceDescriptorV1 } from "./infra/resource-descriptor.v1.js";
101
152
  import { adoptionFactV1 } from "./infra/adoption-fact.v1.js";
102
153
  import { revocationsV1 } from "./registry/revocations.v1.js";
103
154
  import { bootstrapV1 } from "./kernel/bootstrap.v1.js";
104
155
  import { ordinaryAuthorityV1 } from "./kernel/ordinary-authority.v1.js";
156
+ import { standingOrderActivationV1 } from "./kernel/standing-order-activation.v1.js";
105
157
 
106
158
  /** Every profile this version of the package defines, keyed by literal.
107
159
  * Profile modules are added here as they are extracted; the rules test
@@ -111,10 +163,16 @@ export const PROFILES: Readonly<Record<string, ProfileEntry>> = {
111
163
  [dispatchConsumeV1.literal]: dispatchConsumeV1,
112
164
  [operationV1.literal]: operationV1,
113
165
  [eventV1.literal]: eventV1,
166
+ [requestV1.literal]: requestV1,
167
+ [decisionV1.literal]: decisionV1,
168
+ [runSummaryV1.literal]: runSummaryV1,
169
+ [refusalV1.literal]: refusalV1,
170
+ [identityBindingV1.literal]: identityBindingV1,
114
171
  [signedLawV1.literal]: signedLawV1,
115
172
  [resourceDescriptorV1.literal]: resourceDescriptorV1,
116
173
  [adoptionFactV1.literal]: adoptionFactV1,
117
174
  [revocationsV1.literal]: revocationsV1,
118
175
  [bootstrapV1.literal]: bootstrapV1,
119
176
  [ordinaryAuthorityV1.literal]: ordinaryAuthorityV1,
177
+ [standingOrderActivationV1.literal]: standingOrderActivationV1,
120
178
  };
@@ -0,0 +1,72 @@
1
+ // dsg.kernel.standing-order-activation/1
2
+ // Owner: dsg-kernel. The record event selects the one standing-order
3
+ // activation that API and worker may resolve. The revocation reference is
4
+ // the activation-time observation only; consumers must independently resolve
5
+ // the current revocation head before every authority use.
6
+ import { type Static, Type } from "@sinclair/typebox";
7
+ import { closed, Orn, Reference, UtcSecond, type ProfileEntry } from "../primitives.js";
8
+
9
+ export const STANDING_ORDER_ACTIVATION_PROFILE = "dsg.kernel.standing-order-activation/1" as const;
10
+ export const STANDING_ORDER_ACTIVATION_EVENT_KIND = "standing_order_activated" as const;
11
+
12
+ const StandingOrderModeSchemaValue = Type.Union([
13
+ Type.Literal("synthetic-test-only"),
14
+ Type.Literal("human-authority"),
15
+ ]);
16
+ export const StandingOrderModeSchema: typeof StandingOrderModeSchemaValue =
17
+ StandingOrderModeSchemaValue;
18
+ export type StandingOrderMode = Static<typeof StandingOrderModeSchema>;
19
+
20
+ /** The immutable descriptor retained with the activation event. */
21
+ const StandingOrderActivationSchemaValue = closed({
22
+ profile: Type.Literal(STANDING_ORDER_ACTIVATION_PROFILE),
23
+ /** Stable identity carried in the descriptor. The event's `activation`
24
+ * reference points to this descriptor, avoiding a digest cycle. */
25
+ activationId: Orn,
26
+ /** Compare-and-set precondition. Null is valid only for the first head. */
27
+ expectedPreviousActivation: Type.Union([Reference, Type.Null()]),
28
+ law: Reference,
29
+ enrollment: Reference,
30
+ intent: Reference,
31
+ roots: Reference,
32
+ /** Activation-time observation. It never substitutes for a current read. */
33
+ revocation: Reference,
34
+ actor: Orn,
35
+ mode: StandingOrderModeSchema,
36
+ activatedAt: UtcSecond,
37
+ });
38
+ export const StandingOrderActivationSchema: typeof StandingOrderActivationSchemaValue =
39
+ StandingOrderActivationSchemaValue;
40
+ export type StandingOrderActivation = Static<typeof StandingOrderActivationSchema>;
41
+
42
+ /** Append-only record event carrying the descriptor selected by the stream head. */
43
+ const StandingOrderActivationEventSchemaValue = closed({
44
+ profile: Type.Literal(STANDING_ORDER_ACTIVATION_PROFILE),
45
+ kind: Type.Literal(STANDING_ORDER_ACTIVATION_EVENT_KIND),
46
+ stream: Orn,
47
+ /** Reference to the canonical descriptor artifact. */
48
+ activation: Reference,
49
+ });
50
+ export const StandingOrderActivationEventSchema: typeof StandingOrderActivationEventSchemaValue =
51
+ StandingOrderActivationEventSchemaValue;
52
+ export type StandingOrderActivationEvent = Static<typeof StandingOrderActivationEventSchema>;
53
+
54
+ /** Detached signature over the canonical activation descriptor bytes. */
55
+ const SignedStandingOrderActivationSchemaValue = closed({
56
+ body: StandingOrderActivationSchema,
57
+ signer: Orn,
58
+ signature: Type.String({ pattern: "^[0-9a-f]{128}$" }),
59
+ });
60
+ export const SignedStandingOrderActivationSchema: typeof SignedStandingOrderActivationSchemaValue =
61
+ SignedStandingOrderActivationSchemaValue;
62
+ export type SignedStandingOrderActivation = Static<typeof SignedStandingOrderActivationSchema>;
63
+
64
+ export const standingOrderActivationV1: ProfileEntry = {
65
+ literal: STANDING_ORDER_ACTIVATION_PROFILE,
66
+ rootShape: "event",
67
+ shapes: {
68
+ activation: StandingOrderActivationSchema,
69
+ signed: SignedStandingOrderActivationSchema,
70
+ event: StandingOrderActivationEventSchema,
71
+ },
72
+ };
package/src/primitives.ts CHANGED
@@ -33,6 +33,14 @@ export const Reference = closed({
33
33
  sha256: Type.String({ pattern: SHA256_PATTERN }),
34
34
  });
35
35
 
36
+ /** A person named on a run. Missing on the wire is null; readers print
37
+ * "Not recorded". Never inferred. */
38
+ export const PersonReference = closed({
39
+ principal: Orn,
40
+ displayName: NonEmptyString,
41
+ source: NonEmptyString,
42
+ });
43
+
36
44
  /** One wire profile: the literal, and every top-level shape that crosses
37
45
  * the seam it names. Shape names are stable identifiers ("request",
38
46
  * "lease", "refusal"); vectors address a shape as "<literal>#<shape>". */
@@ -0,0 +1,27 @@
1
+ // dsg.run.decision/1
2
+ // Owner: dsg-kernel (the decisions route verifies the signature against
3
+ // the decider's recorded public key). A decision is a signature, not a
4
+ // session. The requester may not decide their own run.
5
+ import { type Static, Type } from "@sinclair/typebox";
6
+ import { closed, Hex64, NonEmptyString, Orn, UtcSecond, type ProfileEntry } from "../primitives.js";
7
+
8
+ export const DECISION_PROFILE = "dsg.run.decision/1" as const;
9
+
10
+ const RunDecisionSchemaValue = closed({
11
+ profile: Type.Literal(DECISION_PROFILE),
12
+ runId: NonEmptyString,
13
+ requestDigest: Hex64,
14
+ decision: Type.Union([Type.Literal("approved"), Type.Literal("refused")]),
15
+ cause: Type.Union([NonEmptyString, Type.Null()]),
16
+ decidedAt: UtcSecond,
17
+ decider: Orn,
18
+ signature: NonEmptyString,
19
+ });
20
+ export const RunDecisionSchema: typeof RunDecisionSchemaValue = RunDecisionSchemaValue;
21
+ export type RunDecision = Static<typeof RunDecisionSchema>;
22
+
23
+ export const decisionV1: ProfileEntry = {
24
+ literal: DECISION_PROFILE,
25
+ rootShape: "decision",
26
+ shapes: { decision: RunDecisionSchema },
27
+ };
@@ -0,0 +1,50 @@
1
+ // dsg.run.request/1
2
+ // Owner: dsg-run (POST /requests). The CLI builds this document from an
3
+ // experiment; the plane fills the requester from the door's assertion and
4
+ // never from a field on this shape.
5
+ import { type Static, Type } from "@sinclair/typebox";
6
+ import {
7
+ closed,
8
+ Hex64,
9
+ NonEmptyString,
10
+ Reference,
11
+ SafeInt,
12
+ type ProfileEntry,
13
+ } from "../primitives.js";
14
+
15
+ export const REQUEST_PROFILE = "dsg.run.request/1" as const;
16
+
17
+ const ExperimentRefSchemaValue = closed({
18
+ digest: Hex64,
19
+ title: NonEmptyString,
20
+ workloadClass: NonEmptyString,
21
+ });
22
+ export const ExperimentRefSchema: typeof ExperimentRefSchemaValue = ExperimentRefSchemaValue;
23
+ export type ExperimentRef = Static<typeof ExperimentRefSchema>;
24
+
25
+ const RequestCeilingsSchemaValue = closed({
26
+ maxRunSeconds: SafeInt,
27
+ maxGpuSeconds: SafeInt,
28
+ maxParallelism: SafeInt,
29
+ costBoundMicroUsd: SafeInt,
30
+ });
31
+ export const RequestCeilingsSchema: typeof RequestCeilingsSchemaValue = RequestCeilingsSchemaValue;
32
+ export type RequestCeilings = Static<typeof RequestCeilingsSchema>;
33
+
34
+ const RunRequestSchemaValue = closed({
35
+ profile: Type.Literal(REQUEST_PROFILE),
36
+ experiment: ExperimentRefSchema,
37
+ workload: Reference,
38
+ inputs: Type.Array(Reference, { minItems: 1 }),
39
+ ceilings: RequestCeilingsSchema,
40
+ purpose: NonEmptyString,
41
+ window: NonEmptyString,
42
+ });
43
+ export const RunRequestSchema: typeof RunRequestSchemaValue = RunRequestSchemaValue;
44
+ export type RunRequest = Static<typeof RunRequestSchema>;
45
+
46
+ export const requestV1: ProfileEntry = {
47
+ literal: REQUEST_PROFILE,
48
+ rootShape: "request",
49
+ shapes: { request: RunRequestSchema },
50
+ };
@@ -0,0 +1,42 @@
1
+ // dsg.run.run-summary/1
2
+ // Owner: dsg-run (the plane writes it; the console and kernel status read
3
+ // it). A gate with no decision is waiting, never approved or refused.
4
+ import { type Static, Type } from "@sinclair/typebox";
5
+ import {
6
+ closed,
7
+ Hex64,
8
+ NonEmptyString,
9
+ PersonReference,
10
+ UtcSecond,
11
+ type ProfileEntry,
12
+ } from "../primitives.js";
13
+
14
+ export const RUN_SUMMARY_PROFILE = "dsg.run.run-summary/1" as const;
15
+
16
+ const RunSummaryDecisionSchemaValue = closed({
17
+ outcome: Type.Union([Type.Literal("approved"), Type.Literal("refused")]),
18
+ decider: PersonReference,
19
+ decidedAt: UtcSecond,
20
+ cause: Type.Union([NonEmptyString, Type.Null()]),
21
+ byStandingOrder: Type.Boolean(),
22
+ });
23
+ export const RunSummaryDecisionSchema: typeof RunSummaryDecisionSchemaValue =
24
+ RunSummaryDecisionSchemaValue;
25
+ export type RunSummaryDecision = Static<typeof RunSummaryDecisionSchema>;
26
+
27
+ const RunSummarySchemaValue = closed({
28
+ profile: Type.Literal(RUN_SUMMARY_PROFILE),
29
+ runId: NonEmptyString,
30
+ experimentDigest: Hex64,
31
+ requester: Type.Union([PersonReference, Type.Null()]),
32
+ decision: Type.Union([RunSummaryDecisionSchema, Type.Null()]),
33
+ waitingOn: Type.Union([NonEmptyString, Type.Null()]),
34
+ });
35
+ export const RunSummarySchema: typeof RunSummarySchemaValue = RunSummarySchemaValue;
36
+ export type RunSummary = Static<typeof RunSummarySchema>;
37
+
38
+ export const runSummaryV1: ProfileEntry = {
39
+ literal: RUN_SUMMARY_PROFILE,
40
+ rootShape: "summary",
41
+ shapes: { summary: RunSummarySchema },
42
+ };