@astrale-os/kernel-core 0.9.0-beta.22 → 0.9.0-beta.23

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.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@
6
6
 
7
7
  * remove endpoint, route, serving issuer, Publication ETag, and View placement properties from the
8
8
  Function and UI schema; graph projection now contains declaration meaning only
9
+ ## [0.9.0-beta.23](https://github.com/astrale-os/kernel/compare/kernel-core-v0.9.0-beta.22...kernel-core-v0.9.0-beta.23) (2026-08-29)
10
+
11
+
12
+ ### Features
13
+
14
+ * **api:** carry view iframe requirements ([#531](https://github.com/astrale-os/kernel/issues/531)) ([4eedb0b](https://github.com/astrale-os/kernel/commit/4eedb0b3430f5f642942e913cf1c5806e09b7cf1))
15
+
9
16
  ## [0.9.0-beta.22](https://github.com/astrale-os/kernel/compare/kernel-core-v0.9.0-beta.21...kernel-core-v0.9.0-beta.22) (2026-08-29)
10
17
 
11
18
 
@@ -42,6 +42,10 @@ export declare const View: builder.NodeClass<{
42
42
  };
43
43
  href: string;
44
44
  handshake: "none" | "shell";
45
+ iframe?: {
46
+ sandbox?: string[] | undefined;
47
+ allow?: string[] | undefined;
48
+ } | undefined;
45
49
  issuer: string;
46
50
  etag: string;
47
51
  revision: string;
@@ -81,6 +85,10 @@ export declare const View: builder.NodeClass<{
81
85
  };
82
86
  href: string;
83
87
  handshake: "none" | "shell";
88
+ iframe?: {
89
+ sandbox?: string[] | undefined;
90
+ allow?: string[] | undefined;
91
+ } | undefined;
84
92
  issuer: string;
85
93
  etag: string;
86
94
  revision: string;
@@ -4269,6 +4269,10 @@ declare const KernelDefinitions: {
4269
4269
  };
4270
4270
  href: string;
4271
4271
  handshake: "none" | "shell";
4272
+ iframe?: {
4273
+ sandbox?: string[] | undefined;
4274
+ allow?: string[] | undefined;
4275
+ } | undefined;
4272
4276
  issuer: string;
4273
4277
  etag: string;
4274
4278
  revision: string;
@@ -4308,6 +4312,10 @@ declare const KernelDefinitions: {
4308
4312
  };
4309
4313
  href: string;
4310
4314
  handshake: "none" | "shell";
4315
+ iframe?: {
4316
+ sandbox?: string[] | undefined;
4317
+ allow?: string[] | undefined;
4318
+ } | undefined;
4311
4319
  issuer: string;
4312
4320
  etag: string;
4313
4321
  revision: string;
@@ -5614,6 +5622,41 @@ export declare const AuthorityRelations: Readonly<{
5614
5622
  }>;
5615
5623
  /** Exact authorized Kernel Functions for which pristine Root receives direct can_use authority. */
5616
5624
  export declare const KernelRootFunctions: readonly ((import("@astrale-os/kernel-dsl/v1").ResolvedFunction<{
5625
+ operation: string;
5626
+ domains: ({
5627
+ artifact: {
5628
+ digest: string;
5629
+ mediaType: string;
5630
+ size: number;
5631
+ };
5632
+ currentRevision?: string | null | undefined;
5633
+ } | {
5634
+ publication: {
5635
+ url: string;
5636
+ token?: string | undefined;
5637
+ etag?: string | undefined;
5638
+ };
5639
+ revision?: string | undefined;
5640
+ currentRevision?: string | null | undefined;
5641
+ })[];
5642
+ }, {
5643
+ readonly mode: 'binary';
5644
+ }, "authorized", import("@astrale-os/kernel-dsl/v1").PolicyCheckExpression<import("@astrale-os/kernel-dsl/v1").PolicyRef, import("@astrale-os/kernel-dsl/v1/language").PolicyCheckObject>> & {
5645
+ readonly ref: import("@astrale-os/kernel-dsl/v1").FunctionRef<"install"> & {
5646
+ readonly origin: "kernel.astrale.ai";
5647
+ };
5648
+ readonly key: "kernel.astrale.ai:function.install";
5649
+ }) | (import("@astrale-os/kernel-dsl/v1").ResolvedFunction<{
5650
+ kind: "bundle" | "inspect";
5651
+ origin: string;
5652
+ }, {
5653
+ readonly mode: 'binary';
5654
+ }, "authenticated", import("@astrale-os/kernel-dsl/v1").PolicyCheckExpression<import("@astrale-os/kernel-dsl/v1").PolicyRef, import("@astrale-os/kernel-dsl/v1/language").PolicyCheckObject>> & {
5655
+ readonly ref: import("@astrale-os/kernel-dsl/v1").FunctionRef<"introspect"> & {
5656
+ readonly origin: "kernel.astrale.ai";
5657
+ };
5658
+ readonly key: "kernel.astrale.ai:function.introspect";
5659
+ }) | (import("@astrale-os/kernel-dsl/v1").ResolvedFunction<{
5617
5660
  invocation?: {
5618
5661
  source: string;
5619
5662
  id: string;
@@ -5645,233 +5688,6 @@ export declare const KernelRootFunctions: readonly ((import("@astrale-os/kernel-
5645
5688
  readonly origin: "kernel.astrale.ai";
5646
5689
  };
5647
5690
  readonly key: "kernel.astrale.ai:function.journal";
5648
- }) | (import("@astrale-os/kernel-dsl/v1").ResolvedFunction<{
5649
- ast: {
5650
- format: "astrale.graph.query";
5651
- version: "v6";
5652
- source: {
5653
- kind: "node";
5654
- terms: ({
5655
- kind: "path";
5656
- path: string;
5657
- } | {
5658
- kind: "class";
5659
- class: {
5660
- origin: string;
5661
- kind: "class";
5662
- name: string;
5663
- };
5664
- })[];
5665
- binding: string;
5666
- } | {
5667
- kind: "edge";
5668
- terms: {
5669
- kind: "class";
5670
- class: {
5671
- origin: string;
5672
- kind: "class";
5673
- name: string;
5674
- };
5675
- }[];
5676
- bindings: {
5677
- source: string;
5678
- edge: string;
5679
- target: string;
5680
- };
5681
- };
5682
- steps: ({
5683
- op: "filter";
5684
- binding: string;
5685
- predicate: {
5686
- kind: "class.satisfies";
5687
- class: {
5688
- origin: string;
5689
- kind: "class";
5690
- name: string;
5691
- };
5692
- } | {
5693
- kind: "class.equal";
5694
- class: {
5695
- origin: string;
5696
- kind: "class";
5697
- name: string;
5698
- };
5699
- } | {
5700
- kind: "property.equal";
5701
- property: string;
5702
- value: unknown;
5703
- } | {
5704
- kind: "property.present";
5705
- property: string;
5706
- } | {
5707
- kind: "identity.equal";
5708
- identity: string | {
5709
- source: string;
5710
- target: string;
5711
- class: string;
5712
- };
5713
- };
5714
- } | {
5715
- op: "expand";
5716
- from: string;
5717
- via: {
5718
- origin: string;
5719
- kind: "class";
5720
- name: string;
5721
- }[];
5722
- direction: "incident" | "incoming" | "outgoing";
5723
- bindings: {
5724
- edge: string;
5725
- node: string;
5726
- };
5727
- })[];
5728
- select: {
5729
- kind: "graph";
5730
- binding: string;
5731
- order?: {
5732
- property: string;
5733
- direction: "asc" | "desc";
5734
- unranked: "first" | "last";
5735
- } | undefined;
5736
- } | {
5737
- kind: "nodes";
5738
- binding: string;
5739
- projection: {
5740
- kind: "reference" | "value";
5741
- };
5742
- order?: {
5743
- property: string;
5744
- direction: "asc" | "desc";
5745
- unranked: "first" | "last";
5746
- } | undefined;
5747
- } | {
5748
- kind: "edges";
5749
- binding: string;
5750
- projection: {
5751
- edge: "reference" | "value";
5752
- source: "reference" | "value";
5753
- target: "reference" | "value";
5754
- };
5755
- order?: {
5756
- property: string;
5757
- direction: "asc" | "desc";
5758
- unranked: "first" | "last";
5759
- } | undefined;
5760
- };
5761
- };
5762
- expected?: {
5763
- origin: string;
5764
- revision: string;
5765
- }[] | undefined;
5766
- page: {
5767
- size: number;
5768
- after?: string | undefined;
5769
- };
5770
- }, {
5771
- readonly mode: 'value';
5772
- readonly value: {
5773
- result: {
5774
- kind: "graph";
5775
- graph: {
5776
- nodes: {
5777
- id: string;
5778
- class: string;
5779
- props: Record<string, unknown>;
5780
- }[];
5781
- edges: {
5782
- source: string;
5783
- target: string;
5784
- class: string;
5785
- slug?: import("../../graph/edge/index.js").EdgeSlug | undefined;
5786
- props: Record<string, unknown>;
5787
- }[];
5788
- };
5789
- selection: {
5790
- kind: "node";
5791
- ids: string[];
5792
- } | {
5793
- kind: "edge";
5794
- keys: {
5795
- source: string;
5796
- target: string;
5797
- class: string;
5798
- }[];
5799
- };
5800
- } | {
5801
- kind: "nodes";
5802
- nodes: ({
5803
- kind: "reference";
5804
- value: {
5805
- id: string;
5806
- class: string;
5807
- };
5808
- } | {
5809
- kind: "value";
5810
- value: {
5811
- id: string;
5812
- class: string;
5813
- props: Record<string, unknown>;
5814
- };
5815
- })[];
5816
- } | {
5817
- kind: "edges";
5818
- edges: {
5819
- edge: {
5820
- kind: "reference";
5821
- value: {
5822
- source: string;
5823
- target: string;
5824
- class: string;
5825
- };
5826
- } | {
5827
- kind: "value";
5828
- value: {
5829
- source: string;
5830
- target: string;
5831
- class: string;
5832
- slug?: import("../../graph/edge/index.js").EdgeSlug | undefined;
5833
- props: Record<string, unknown>;
5834
- };
5835
- };
5836
- source: {
5837
- kind: "reference";
5838
- value: {
5839
- id: string;
5840
- class: string;
5841
- };
5842
- } | {
5843
- kind: "value";
5844
- value: {
5845
- id: string;
5846
- class: string;
5847
- props: Record<string, unknown>;
5848
- };
5849
- };
5850
- target: {
5851
- kind: "reference";
5852
- value: {
5853
- id: string;
5854
- class: string;
5855
- };
5856
- } | {
5857
- kind: "value";
5858
- value: {
5859
- id: string;
5860
- class: string;
5861
- props: Record<string, unknown>;
5862
- };
5863
- };
5864
- }[];
5865
- };
5866
- page: {
5867
- next?: string | undefined;
5868
- };
5869
- };
5870
- }, "authorized", import("@astrale-os/kernel-dsl/v1").PolicyCheckExpression<import("@astrale-os/kernel-dsl/v1").PolicyRef, import("@astrale-os/kernel-dsl/v1/language").PolicyCheckObject>> & {
5871
- readonly ref: import("@astrale-os/kernel-dsl/v1").FunctionRef<"query"> & {
5872
- readonly origin: "kernel.astrale.ai";
5873
- };
5874
- readonly key: "kernel.astrale.ai:function.query";
5875
5691
  }) | (import("@astrale-os/kernel-dsl/v1").ResolvedFunction<{
5876
5692
  ast: {
5877
5693
  format: "astrale.graph.mutation";
@@ -6375,40 +6191,232 @@ export declare const KernelRootFunctions: readonly ((import("@astrale-os/kernel-
6375
6191
  };
6376
6192
  readonly key: "kernel.astrale.ai:function.provision";
6377
6193
  }) | (import("@astrale-os/kernel-dsl/v1").ResolvedFunction<{
6378
- operation: string;
6379
- domains: ({
6380
- artifact: {
6381
- digest: string;
6382
- mediaType: string;
6383
- size: number;
6194
+ ast: {
6195
+ format: "astrale.graph.query";
6196
+ version: "v6";
6197
+ source: {
6198
+ kind: "node";
6199
+ terms: ({
6200
+ kind: "path";
6201
+ path: string;
6202
+ } | {
6203
+ kind: "class";
6204
+ class: {
6205
+ origin: string;
6206
+ kind: "class";
6207
+ name: string;
6208
+ };
6209
+ })[];
6210
+ binding: string;
6211
+ } | {
6212
+ kind: "edge";
6213
+ terms: {
6214
+ kind: "class";
6215
+ class: {
6216
+ origin: string;
6217
+ kind: "class";
6218
+ name: string;
6219
+ };
6220
+ }[];
6221
+ bindings: {
6222
+ source: string;
6223
+ edge: string;
6224
+ target: string;
6225
+ };
6384
6226
  };
6385
- currentRevision?: string | null | undefined;
6386
- } | {
6387
- publication: {
6388
- url: string;
6389
- token?: string | undefined;
6390
- etag?: string | undefined;
6227
+ steps: ({
6228
+ op: "filter";
6229
+ binding: string;
6230
+ predicate: {
6231
+ kind: "class.satisfies";
6232
+ class: {
6233
+ origin: string;
6234
+ kind: "class";
6235
+ name: string;
6236
+ };
6237
+ } | {
6238
+ kind: "class.equal";
6239
+ class: {
6240
+ origin: string;
6241
+ kind: "class";
6242
+ name: string;
6243
+ };
6244
+ } | {
6245
+ kind: "property.equal";
6246
+ property: string;
6247
+ value: unknown;
6248
+ } | {
6249
+ kind: "property.present";
6250
+ property: string;
6251
+ } | {
6252
+ kind: "identity.equal";
6253
+ identity: string | {
6254
+ source: string;
6255
+ target: string;
6256
+ class: string;
6257
+ };
6258
+ };
6259
+ } | {
6260
+ op: "expand";
6261
+ from: string;
6262
+ via: {
6263
+ origin: string;
6264
+ kind: "class";
6265
+ name: string;
6266
+ }[];
6267
+ direction: "incident" | "incoming" | "outgoing";
6268
+ bindings: {
6269
+ edge: string;
6270
+ node: string;
6271
+ };
6272
+ })[];
6273
+ select: {
6274
+ kind: "graph";
6275
+ binding: string;
6276
+ order?: {
6277
+ property: string;
6278
+ direction: "asc" | "desc";
6279
+ unranked: "first" | "last";
6280
+ } | undefined;
6281
+ } | {
6282
+ kind: "nodes";
6283
+ binding: string;
6284
+ projection: {
6285
+ kind: "reference" | "value";
6286
+ };
6287
+ order?: {
6288
+ property: string;
6289
+ direction: "asc" | "desc";
6290
+ unranked: "first" | "last";
6291
+ } | undefined;
6292
+ } | {
6293
+ kind: "edges";
6294
+ binding: string;
6295
+ projection: {
6296
+ edge: "reference" | "value";
6297
+ source: "reference" | "value";
6298
+ target: "reference" | "value";
6299
+ };
6300
+ order?: {
6301
+ property: string;
6302
+ direction: "asc" | "desc";
6303
+ unranked: "first" | "last";
6304
+ } | undefined;
6391
6305
  };
6392
- revision?: string | undefined;
6393
- currentRevision?: string | null | undefined;
6394
- })[];
6395
- }, {
6396
- readonly mode: 'binary';
6397
- }, "authorized", import("@astrale-os/kernel-dsl/v1").PolicyCheckExpression<import("@astrale-os/kernel-dsl/v1").PolicyRef, import("@astrale-os/kernel-dsl/v1/language").PolicyCheckObject>> & {
6398
- readonly ref: import("@astrale-os/kernel-dsl/v1").FunctionRef<"install"> & {
6399
- readonly origin: "kernel.astrale.ai";
6400
6306
  };
6401
- readonly key: "kernel.astrale.ai:function.install";
6402
- }) | (import("@astrale-os/kernel-dsl/v1").ResolvedFunction<{
6403
- kind: "bundle" | "inspect";
6404
- origin: string;
6307
+ expected?: {
6308
+ origin: string;
6309
+ revision: string;
6310
+ }[] | undefined;
6311
+ page: {
6312
+ size: number;
6313
+ after?: string | undefined;
6314
+ };
6405
6315
  }, {
6406
- readonly mode: 'binary';
6407
- }, "authenticated", import("@astrale-os/kernel-dsl/v1").PolicyCheckExpression<import("@astrale-os/kernel-dsl/v1").PolicyRef, import("@astrale-os/kernel-dsl/v1/language").PolicyCheckObject>> & {
6408
- readonly ref: import("@astrale-os/kernel-dsl/v1").FunctionRef<"introspect"> & {
6316
+ readonly mode: 'value';
6317
+ readonly value: {
6318
+ result: {
6319
+ kind: "graph";
6320
+ graph: {
6321
+ nodes: {
6322
+ id: string;
6323
+ class: string;
6324
+ props: Record<string, unknown>;
6325
+ }[];
6326
+ edges: {
6327
+ source: string;
6328
+ target: string;
6329
+ class: string;
6330
+ slug?: import("../../graph/edge/index.js").EdgeSlug | undefined;
6331
+ props: Record<string, unknown>;
6332
+ }[];
6333
+ };
6334
+ selection: {
6335
+ kind: "node";
6336
+ ids: string[];
6337
+ } | {
6338
+ kind: "edge";
6339
+ keys: {
6340
+ source: string;
6341
+ target: string;
6342
+ class: string;
6343
+ }[];
6344
+ };
6345
+ } | {
6346
+ kind: "nodes";
6347
+ nodes: ({
6348
+ kind: "reference";
6349
+ value: {
6350
+ id: string;
6351
+ class: string;
6352
+ };
6353
+ } | {
6354
+ kind: "value";
6355
+ value: {
6356
+ id: string;
6357
+ class: string;
6358
+ props: Record<string, unknown>;
6359
+ };
6360
+ })[];
6361
+ } | {
6362
+ kind: "edges";
6363
+ edges: {
6364
+ edge: {
6365
+ kind: "reference";
6366
+ value: {
6367
+ source: string;
6368
+ target: string;
6369
+ class: string;
6370
+ };
6371
+ } | {
6372
+ kind: "value";
6373
+ value: {
6374
+ source: string;
6375
+ target: string;
6376
+ class: string;
6377
+ slug?: import("../../graph/edge/index.js").EdgeSlug | undefined;
6378
+ props: Record<string, unknown>;
6379
+ };
6380
+ };
6381
+ source: {
6382
+ kind: "reference";
6383
+ value: {
6384
+ id: string;
6385
+ class: string;
6386
+ };
6387
+ } | {
6388
+ kind: "value";
6389
+ value: {
6390
+ id: string;
6391
+ class: string;
6392
+ props: Record<string, unknown>;
6393
+ };
6394
+ };
6395
+ target: {
6396
+ kind: "reference";
6397
+ value: {
6398
+ id: string;
6399
+ class: string;
6400
+ };
6401
+ } | {
6402
+ kind: "value";
6403
+ value: {
6404
+ id: string;
6405
+ class: string;
6406
+ props: Record<string, unknown>;
6407
+ };
6408
+ };
6409
+ }[];
6410
+ };
6411
+ page: {
6412
+ next?: string | undefined;
6413
+ };
6414
+ };
6415
+ }, "authorized", import("@astrale-os/kernel-dsl/v1").PolicyCheckExpression<import("@astrale-os/kernel-dsl/v1").PolicyRef, import("@astrale-os/kernel-dsl/v1/language").PolicyCheckObject>> & {
6416
+ readonly ref: import("@astrale-os/kernel-dsl/v1").FunctionRef<"query"> & {
6409
6417
  readonly origin: "kernel.astrale.ai";
6410
6418
  };
6411
- readonly key: "kernel.astrale.ai:function.introspect";
6419
+ readonly key: "kernel.astrale.ai:function.query";
6412
6420
  }) | (import("@astrale-os/kernel-dsl/v1").ResolvedFunction<{
6413
6421
  operation: string;
6414
6422
  origin: string;
@@ -6508,6 +6516,10 @@ export declare const KernelRootFunctions: readonly ((import("@astrale-os/kernel-
6508
6516
  };
6509
6517
  href: string;
6510
6518
  handshake: "none" | "shell";
6519
+ iframe?: {
6520
+ sandbox?: string[] | undefined;
6521
+ allow?: string[] | undefined;
6522
+ } | undefined;
6511
6523
  issuer: string;
6512
6524
  etag: string;
6513
6525
  revision: string;
@@ -24,6 +24,10 @@ export declare const viewResolveOutput: z.ZodObject<{
24
24
  none: "none";
25
25
  shell: "shell";
26
26
  }>;
27
+ iframe: z.ZodOptional<z.ZodObject<{
28
+ sandbox: z.ZodOptional<z.ZodArray<z.ZodString>>;
29
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
+ }, z.core.$strict>>;
27
31
  issuer: z.ZodString;
28
32
  etag: z.ZodString;
29
33
  revision: z.ZodString;
@@ -13,6 +13,10 @@ const declaration = z.strictObject({
13
13
  z.strictObject({ kind: z.literal('definition'), definitions: z.array(definition).min(1) }),
14
14
  ]),
15
15
  });
16
+ const iframeRequirements = z.strictObject({
17
+ sandbox: z.array(z.string()).optional(),
18
+ allow: z.array(z.string()).optional(),
19
+ });
16
20
  export const viewResolveInput = z.strictObject({ target: z.string().min(1) });
17
21
  export const viewResolveOutput = z.strictObject({
18
22
  snapshot: z.string().min(1),
@@ -21,6 +25,7 @@ export const viewResolveOutput = z.strictObject({
21
25
  declaration,
22
26
  href: z.string().min(1),
23
27
  handshake: z.enum(['shell', 'none']),
28
+ iframe: iframeRequirements.optional(),
24
29
  issuer: z.string().min(1),
25
30
  etag: z.string().min(1),
26
31
  revision: z.string().min(1),
@@ -922,6 +922,10 @@ export declare const ViewMethods: Readonly<{
922
922
  };
923
923
  href: string;
924
924
  handshake: "none" | "shell";
925
+ iframe?: {
926
+ sandbox?: string[] | undefined;
927
+ allow?: string[] | undefined;
928
+ } | undefined;
925
929
  issuer: string;
926
930
  etag: string;
927
931
  revision: string;
@@ -22,6 +22,10 @@ export declare const ViewResolve: builder.Method<builder.CallableProjection<{
22
22
  };
23
23
  href: string;
24
24
  handshake: "none" | "shell";
25
+ iframe?: {
26
+ sandbox?: string[] | undefined;
27
+ allow?: string[] | undefined;
28
+ } | undefined;
25
29
  issuer: string;
26
30
  etag: string;
27
31
  revision: string;
@@ -6,10 +6,15 @@ export interface ResolvedView {
6
6
  readonly declaration: ViewDeclaration;
7
7
  readonly href: string;
8
8
  readonly handshake: 'shell' | 'none';
9
+ readonly iframe?: IframeRequirements;
9
10
  readonly issuer: IssuerId;
10
11
  readonly etag: `sha256:${string}`;
11
12
  readonly revision: Revision;
12
13
  }
14
+ export interface IframeRequirements {
15
+ readonly sandbox?: readonly string[];
16
+ readonly allow?: readonly string[];
17
+ }
13
18
  type ViewDeclaration = Omit<ViewDefinition, 'ref'>;
14
19
  export interface ViewResolution {
15
20
  readonly snapshot: `sha256:${string}`;
@@ -23,11 +23,13 @@ export function acceptViewResolution(input) {
23
23
  if (!issuer.is(view.issuer))
24
24
  invalid(`Resolved View ${index} issuer is not canonical.`);
25
25
  const declaration = acceptDeclaration(view.declaration, index);
26
+ const iframe = acceptIframeRequirements(view.iframe, view.handshake, index);
26
27
  return Object.freeze({
27
28
  key,
28
29
  declaration,
29
30
  href: view.href,
30
31
  handshake: view.handshake,
32
+ ...(iframe === undefined ? {} : { iframe }),
31
33
  issuer: view.issuer,
32
34
  etag: digest(view.etag, `Resolved View ${index} ETag`),
33
35
  revision: digest(view.revision, `Resolved View ${index} revision`),
@@ -43,6 +45,85 @@ export function acceptViewResolution(input) {
43
45
  views: Object.freeze(views),
44
46
  });
45
47
  }
48
+ const IFRAME_TOKEN = /^[a-z][a-z0-9-]*$/u;
49
+ function acceptIframeRequirements(input, handshake, viewIndex) {
50
+ if (input === undefined)
51
+ return undefined;
52
+ if (input === null || typeof input !== 'object' || Array.isArray(input)) {
53
+ invalid(`Resolved View ${viewIndex} iframe requirements are invalid.`);
54
+ }
55
+ const prototype = Object.getPrototypeOf(input);
56
+ if (prototype !== Object.prototype && prototype !== null) {
57
+ invalid(`Resolved View ${viewIndex} iframe requirements are invalid.`);
58
+ }
59
+ const value = input;
60
+ if (Reflect.ownKeys(value).some((key) => key !== 'sandbox' && key !== 'allow')) {
61
+ invalid(`Resolved View ${viewIndex} iframe requirements contain unknown fields.`);
62
+ }
63
+ const sandbox = acceptTokens(dataValue(value, 'sandbox', viewIndex), viewIndex, 'sandbox');
64
+ const allow = acceptTokens(dataValue(value, 'allow', viewIndex), viewIndex, 'allow');
65
+ const baselineSandbox = new Set(handshake === 'shell' ? ['allow-same-origin', 'allow-scripts'] : ['allow-scripts']);
66
+ const baselineAllow = new Set(handshake === 'shell' ? ['clipboard-write'] : []);
67
+ if (sandbox.some((token) => baselineSandbox.has(token)) ||
68
+ allow.some((token) => baselineAllow.has(token))) {
69
+ invalid(`Resolved View ${viewIndex} iframe requirements repeat a fixed handshake baseline.`);
70
+ }
71
+ const tokens = new Set(sandbox);
72
+ if (tokens.has('allow-popups-to-escape-sandbox') && !tokens.has('allow-popups')) {
73
+ invalid(`Resolved View ${viewIndex} popup escape requires popup authority.`);
74
+ }
75
+ if (tokens.has('allow-top-navigation') && tokens.has('allow-top-navigation-by-user-activation')) {
76
+ invalid(`Resolved View ${viewIndex} iframe navigation requirements are redundant.`);
77
+ }
78
+ if (tokens.has('allow-top-navigation-to-custom-protocols') &&
79
+ (tokens.has('allow-top-navigation') || tokens.has('allow-popups'))) {
80
+ invalid(`Resolved View ${viewIndex} custom-protocol requirements are redundant.`);
81
+ }
82
+ if (sandbox.length === 0 && allow.length === 0) {
83
+ invalid(`Resolved View ${viewIndex} empty iframe requirements must be omitted.`);
84
+ }
85
+ return Object.freeze({ sandbox: Object.freeze(sandbox), allow: Object.freeze(allow) });
86
+ }
87
+ function dataValue(input, key, viewIndex) {
88
+ const descriptor = Object.getOwnPropertyDescriptor(input, key);
89
+ if (descriptor === undefined)
90
+ return undefined;
91
+ if (!('value' in descriptor)) {
92
+ invalid(`Resolved View ${viewIndex} iframe requirements are invalid.`);
93
+ }
94
+ return descriptor.value;
95
+ }
96
+ function acceptTokens(input, viewIndex, field) {
97
+ if (input === undefined)
98
+ return [];
99
+ if (!Array.isArray(input))
100
+ invalid(`Resolved View ${viewIndex} iframe ${field} is invalid.`);
101
+ const descriptors = Object.getOwnPropertyDescriptors(input);
102
+ const values = [];
103
+ for (let index = 0; index < input.length; index += 1) {
104
+ const descriptor = descriptors[String(index)];
105
+ if (descriptor === undefined ||
106
+ !('value' in descriptor) ||
107
+ typeof descriptor.value !== 'string' ||
108
+ !IFRAME_TOKEN.test(descriptor.value)) {
109
+ invalid(`Resolved View ${viewIndex} iframe ${field} contains an invalid token.`);
110
+ }
111
+ values.push(descriptor.value);
112
+ }
113
+ for (const key of Reflect.ownKeys(descriptors)) {
114
+ if (key === 'length')
115
+ continue;
116
+ if (typeof key !== 'string' || !/^(0|[1-9][0-9]*)$/u.test(key) || Number(key) >= input.length) {
117
+ invalid(`Resolved View ${viewIndex} iframe ${field} is invalid.`);
118
+ }
119
+ }
120
+ for (let index = 1; index < values.length; index += 1) {
121
+ if (values[index - 1] >= values[index]) {
122
+ invalid(`Resolved View ${viewIndex} iframe ${field} is not in strict canonical order.`);
123
+ }
124
+ }
125
+ return values;
126
+ }
46
127
  function acceptDeclaration(input, viewIndex) {
47
128
  if (input.target.kind === 'domain') {
48
129
  return Object.freeze({
@@ -26,6 +26,10 @@ export declare const resolve: import("./model.js").MethodSyscall<Readonly<{
26
26
  };
27
27
  href: string;
28
28
  handshake: "none" | "shell";
29
+ iframe?: {
30
+ sandbox?: string[] | undefined;
31
+ allow?: string[] | undefined;
32
+ } | undefined;
29
33
  issuer: string;
30
34
  etag: string;
31
35
  revision: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrale-os/kernel-core",
3
- "version": "0.9.0-beta.22",
3
+ "version": "0.9.0-beta.23",
4
4
  "description": "Astrale Kernel Core - Types, Invariants, and Pure Logic",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {