@hraness/slopcamera 3.2.8 → 3.3.1

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 (150) hide show
  1. package/README.md +29 -9
  2. package/apps/desktop/application/context.ts +6 -0
  3. package/apps/desktop/application/default-registry.ts +26 -0
  4. package/apps/desktop/application/operation.ts +14 -1
  5. package/apps/desktop/application/operations/index.ts +4 -0
  6. package/apps/desktop/application/operations/spatial-behavior.ts +151 -0
  7. package/apps/desktop/application/operations/spatial-direction.ts +222 -0
  8. package/apps/desktop/application/operations/spatial-rendered-audit.ts +174 -0
  9. package/apps/desktop/application/operations/spatial-review.ts +194 -0
  10. package/apps/desktop/application/operations/spatial-scene.ts +25 -1
  11. package/apps/desktop/application/registry.ts +2 -2
  12. package/apps/desktop/application/spatial-asset-admission.ts +201 -0
  13. package/apps/desktop/application/spatial-assets.ts +160 -31
  14. package/apps/desktop/application/spatial-render.ts +217 -20
  15. package/apps/desktop/application/spatial-rendered-audit.ts +273 -0
  16. package/apps/desktop/application/spatial-review.ts +361 -0
  17. package/apps/desktop/application/spatial-spz.ts +48 -3
  18. package/apps/desktop/application/spatial-world-import.ts +26 -5
  19. package/apps/desktop/application/spatial-world-metadata.ts +105 -0
  20. package/apps/desktop/cli/args.ts +514 -11
  21. package/apps/desktop/cli/capability-manifest.ts +374 -0
  22. package/apps/desktop/cli/cinema-renderer.ts +608 -0
  23. package/apps/desktop/cli/command-host-resources.ts +29 -1
  24. package/apps/desktop/cli/commands.ts +1188 -4
  25. package/apps/desktop/cli/gateway-review-provider.ts +334 -0
  26. package/apps/desktop/cli/help.ts +172 -6
  27. package/apps/desktop/cli/main.ts +3 -3
  28. package/apps/desktop/cli/portable-surface.ts +6 -1
  29. package/apps/desktop/cli/spatial-asset-service.ts +124 -0
  30. package/apps/desktop/cli/spatial-design-service.ts +237 -0
  31. package/apps/desktop/cli/spatial-generate-service.ts +370 -0
  32. package/apps/desktop/cli/spatial-scene-service.ts +268 -4
  33. package/apps/desktop/cli/workflow-code.ts +1 -1
  34. package/apps/desktop/code/semantic-builder.ts +24 -0
  35. package/apps/desktop/contracts/cinema.ts +736 -0
  36. package/apps/desktop/contracts/index.ts +1 -0
  37. package/apps/desktop/contracts/spatial-asset.ts +16 -0
  38. package/apps/desktop/contracts/spatial-world.ts +26 -3
  39. package/apps/desktop/core/cinema-plan.ts +1320 -0
  40. package/apps/desktop/core/index.ts +1 -0
  41. package/apps/desktop/core/storage.ts +75 -0
  42. package/apps/desktop/dist/cli/main.js +725 -273
  43. package/apps/desktop/html-overlay/spatial.ts +619 -57
  44. package/apps/desktop/workflows/cinematic-world.ts +127 -0
  45. package/apps/desktop/workflows/index.ts +6 -0
  46. package/dist/cli.js +25 -429
  47. package/dist/code/advanced.js +1 -269
  48. package/dist/code/index.js +16 -2239
  49. package/dist/generate.js +1 -23
  50. package/dist/host-resources.js +1 -25
  51. package/dist/index-0bbesn4m.js +35 -0
  52. package/dist/index-296qhpf2.js +3 -0
  53. package/dist/index-3cxf2c58.js +3 -0
  54. package/dist/index-77fjfg9f.js +3 -0
  55. package/dist/index-80a36bc0.js +3 -0
  56. package/dist/index-a3vvs3rf.js +3 -0
  57. package/dist/index-b3geqczn.js +5 -0
  58. package/dist/index-cgpkyjqa.js +3 -0
  59. package/dist/index-f0ptv8dm.js +7 -0
  60. package/dist/index-grk47tgs.js +3 -0
  61. package/dist/index-qry58nj2.js +10 -0
  62. package/dist/index.js +1 -226
  63. package/dist/operations.js +1 -28
  64. package/dist/skill-install-gx7afxsd.js +2 -0
  65. package/dist/vectorize/worker.js +1 -141
  66. package/dist/workflow.js +1 -15
  67. package/docs/README.md +5 -1
  68. package/package.json +7 -5
  69. package/skills/slopcamera/SKILL.md +6 -1
  70. package/skills/slopcamera/references/directed-scenes.md +22 -2
  71. package/skills/slopcamera/references/gateway-media.md +15 -1
  72. package/skills/slopcamera/references/image-galleries.md +166 -0
  73. package/skills/slopcamera/references/install.md +1 -1
  74. package/skills/slopcamera/references/parametric-design.md +14 -0
  75. package/skills/slopcamera/references/scene-building.md +32 -0
  76. package/skills/slopcamera/references/social-collage-banners.md +204 -0
  77. package/skills/slopcamera/references/workflows-sdk.md +3 -3
  78. package/skills/slopcamera/scripts/compose-social-collage-banner.ts +728 -0
  79. package/src/capability-manifest.ts +361 -0
  80. package/src/cli.ts +222 -4
  81. package/src/code/canonical-json.ts +9 -0
  82. package/src/generate.ts +2 -2
  83. package/src/icon.ts +1111 -0
  84. package/src/image-gallery.ts +1049 -0
  85. package/src/index.ts +11 -0
  86. package/src/mcp/boundary.ts +11 -11
  87. package/src/mcp/index.ts +3 -0
  88. package/src/mcp/server.ts +2 -1
  89. package/src/mcp/tools.ts +1642 -130
  90. package/src/mcp/types.ts +19 -0
  91. package/src/operations.ts +412 -0
  92. package/src/portable-capability-manifest.ts +67 -0
  93. package/src/scene-gallery.ts +184 -0
  94. package/src/spatial-scene/asset-admission.ts +183 -0
  95. package/src/spatial-scene/audit-rendered.ts +692 -0
  96. package/src/spatial-scene/audit.ts +617 -0
  97. package/src/spatial-scene/behavior-audit.ts +252 -0
  98. package/src/spatial-scene/behavior-bake.ts +233 -0
  99. package/src/spatial-scene/behavior-fns.ts +585 -0
  100. package/src/spatial-scene/behavior-gallery.ts +109 -0
  101. package/src/spatial-scene/behavior-stdlib.ts +323 -0
  102. package/src/spatial-scene/behavior-trace.ts +325 -0
  103. package/src/spatial-scene/behavior.ts +618 -0
  104. package/src/spatial-scene/build.ts +632 -0
  105. package/src/spatial-scene/camera-rig.ts +125 -0
  106. package/src/spatial-scene/camera-track.ts +4 -2
  107. package/src/spatial-scene/character.ts +124 -0
  108. package/src/spatial-scene/contracts.ts +75 -7
  109. package/src/spatial-scene/design-templates.ts +351 -0
  110. package/src/spatial-scene/design.ts +327 -0
  111. package/src/spatial-scene/direction-compile.ts +584 -0
  112. package/src/spatial-scene/direction.ts +122 -0
  113. package/src/spatial-scene/effects.ts +149 -0
  114. package/src/spatial-scene/evaluate.ts +109 -29
  115. package/src/spatial-scene/gallery.ts +277 -0
  116. package/src/spatial-scene/generate.ts +239 -0
  117. package/src/spatial-scene/geometry-native.ts +165 -0
  118. package/src/spatial-scene/geometry.ts +1216 -0
  119. package/src/spatial-scene/gltf.ts +600 -77
  120. package/src/spatial-scene/identity.ts +55 -2
  121. package/src/spatial-scene/index.ts +36 -0
  122. package/src/spatial-scene/inspect.ts +35 -6
  123. package/src/spatial-scene/material-lighting.ts +609 -0
  124. package/src/spatial-scene/math.ts +21 -4
  125. package/src/spatial-scene/motion-evidence.ts +88 -0
  126. package/src/spatial-scene/parametric.ts +765 -0
  127. package/src/spatial-scene/particle-preparation.ts +183 -0
  128. package/src/spatial-scene/particle.ts +195 -0
  129. package/src/spatial-scene/patch.ts +109 -15
  130. package/src/spatial-scene/performance.ts +1613 -0
  131. package/src/spatial-scene/probe.ts +137 -0
  132. package/src/spatial-scene/recipe-pack.ts +86 -0
  133. package/src/spatial-scene/render-effects.ts +240 -0
  134. package/src/spatial-scene/review.ts +639 -0
  135. package/src/spatial-scene/simulation-bake.ts +206 -0
  136. package/src/spatial-scene/simulation.ts +187 -0
  137. package/src/spatial-scene/solve.ts +366 -0
  138. package/src/spatial-scene/temporal-audit.ts +354 -0
  139. package/src/version.ts +1 -1
  140. package/dist/index-42zsesc1.js +0 -2257
  141. package/dist/index-7131pg1c.js +0 -1820
  142. package/dist/index-7308egqr.js +0 -48
  143. package/dist/index-8txs6fkn.js +0 -712
  144. package/dist/index-fava6pge.js +0 -192
  145. package/dist/index-h1k0fnjq.js +0 -2363
  146. package/dist/index-r7gdhmsp.js +0 -424
  147. package/dist/index-sh6xbav6.js +0 -1219
  148. package/dist/index-z1w83f81.js +0 -4
  149. package/dist/index-zfnddgay.js +0 -2029
  150. package/dist/skill-install-dh0ntqba.js +0 -10
package/README.md CHANGED
@@ -33,15 +33,14 @@ project database.
33
33
 
34
34
  ## Install Slopcamera
35
35
 
36
- The source tree prepares v3.2.8 with optional support in the CLI, agent skill, native menu, and public footer.
37
- The install below stays on the verified v3.2.6 release until publication completes.
36
+ Slopcamera v3.2.8 adds optional support in the CLI, agent skill, native menu, and public footer.
38
37
 
39
38
  Install [Bun 1.3.14 or newer](https://bun.sh), then install the verified
40
- [Slopcamera v3.2.6 release](https://github.com/hraness/slopcamera/releases/tag/v3.2.6)
39
+ [Slopcamera v3.2.8 release](https://github.com/hraness/slopcamera/releases/tag/v3.2.8)
41
40
  from its canonical archive:
42
41
 
43
42
  ```sh
44
- bun add --global https://github.com/hraness/slopcamera/releases/download/v3.2.6/hraness-slopcamera-3.2.6.tgz
43
+ bun add --global https://github.com/hraness/slopcamera/releases/download/v3.2.8/hraness-slopcamera-3.2.8.tgz
45
44
  slopcamera skill install --target agents
46
45
  ```
47
46
 
@@ -135,10 +134,30 @@ GPU path. Spark admits saved splat worlds for local camera direction.
135
134
  > mount the product diagram on a screen in the scene, and show me contact frames
136
135
  > before rendering the video.
137
136
 
138
- The portable GLB profile has a defined geometry and material subset. Saved splats
137
+ The portable GLB profile has a defined geometry and material subset; the
138
+ additive rigged profile admits bounded skins and morph targets. Saved splats
139
139
  capture appearance; they do not establish collision geometry or editable native
140
140
  meshes. See [Directed scenes](docs/spatial-scenes.md).
141
141
 
142
+ Current source adds the cinematic planning loop: a `slopcamera.spatial-direction`
143
+ document describes beats, actions, camera coverage, and look intents, compiles
144
+ into proposed performance/camera/cinema/material-lighting/shot documents, and
145
+ fans out into bounded galleries per axis. Declared effects bind into renders,
146
+ and a temporal audit samples evidence at explicit times — all deterministic,
147
+ all reviewable before anything is selected.
148
+
149
+ ```sh
150
+ slopcamera scene direction check direction.json --scene world.json --json
151
+ slopcamera scene direction gallery direction.json --scene world.json --axis camera --output gallery.json --json
152
+ slopcamera workflows plan cinematic-world --input pack-input.json --json
153
+ ```
154
+
155
+ The `cinematic-world` workflow consumes one inert recipe pack — a bounded,
156
+ content-addressed JSON document an agent can author — and stops before
157
+ selection. Registration and selection stay explicit `scene project` operations.
158
+ See [Direct a cinematic world](docs/how-to/direct-cinematic-worlds.md) and the
159
+ [extension architecture](docs/extension-architecture.md).
160
+
142
161
  ### Film native worlds and educational animation
143
162
 
144
163
  The current source build can direct Blender for detailed sets, materials,
@@ -255,8 +274,9 @@ declarative graphs, approvals, and resuming work.
255
274
  - **Trusted code is not sandboxed.** Native Python and caller-authored Bun
256
275
  workflows run with the current user's access. Hashes and receipts identify
257
276
  observed inputs and outputs; they do not make arbitrary code hermetic.
258
- - **MCP is a subset.** Its fixed tools check and render diagrams, vectorize
259
- images, and generate images. It does not expose every local CLI operation.
277
+ - **MCP is a subset.** Its fixed tools check and render diagrams, plan and audit
278
+ scenes, and run the bounded portable operations. It does not expose every
279
+ local CLI operation and never mutates project state.
260
280
 
261
281
  ## Design and trust
262
282
 
@@ -280,9 +300,9 @@ See [Architecture](docs/architecture.md), [`SECURITY.md`](SECURITY.md),
280
300
  ## Documentation
281
301
 
282
302
  - **Learn:** [Your first diagram](docs/tutorials/first-diagram.md) · [Your first native film](docs/tutorials/first-native-film.md).
283
- - **Make a result:** [Edit video](docs/how-to/edit-video.md) · [Generate media](docs/how-to/generate-media.md) · [Run workflows](docs/how-to/run-workflows.md) · [Educational video](docs/how-to/educational-video.md).
303
+ - **Make a result:** [Edit video](docs/how-to/edit-video.md) · [Generate media](docs/how-to/generate-media.md) · [Run workflows](docs/how-to/run-workflows.md) · [Educational video](docs/how-to/educational-video.md) · [Direct a cinematic world](docs/how-to/direct-cinematic-worlds.md).
284
304
  - **Look up support:** [Capabilities and release availability](docs/reference/capabilities.md) · [SDK entrypoints](docs/reference/sdk.md) · [Creative tools](docs/html-overlay-creative-toolkit.md).
285
- - **Understand the system:** [Architecture](docs/architecture.md) · [Native studio](docs/studio.md) · [Directed scenes](docs/spatial-scenes.md).
305
+ - **Understand the system:** [Architecture](docs/architecture.md) · [Native studio](docs/studio.md) · [Directed scenes](docs/spatial-scenes.md) · [Extension architecture](docs/extension-architecture.md).
286
306
 
287
307
  The [documentation index](docs/README.md) connects these paths.
288
308
 
@@ -1,8 +1,10 @@
1
1
  import type { HostResourceLease } from "@hraness/slopcamera/host-resources";
2
2
 
3
+ import type { SpatialReviewProvider } from "../../../src/spatial-scene/review";
3
4
  import type { ApplicationStudioAuthorization, ApplicationStudioPort } from "./studio-port";
4
5
  import type { ApplicationGatewayPort } from "./gateway-port";
5
6
  import type { HtmlOverlayRenderer } from "./html-overlay-renderer";
7
+ import type { ApplicationSpatialReviewAuthorization } from "./spatial-review";
6
8
 
7
9
  export interface ApplicationPaths {
8
10
  readonly artifactRoot: string;
@@ -79,6 +81,10 @@ export interface ApplicationContext {
79
81
  readonly gatewayPort?: ApplicationGatewayPort;
80
82
  readonly studioPort?: ApplicationStudioPort;
81
83
  readonly studioAuthorization?: ApplicationStudioAuthorization;
84
+ /** Bounded beauty-frame critique seam; absent means scene.review fails closed. */
85
+ readonly spatialReviewProvider?: SpatialReviewProvider;
86
+ /** Invocation-scoped cloud-upload consent envelope for scene.review. */
87
+ readonly spatialReviewAuthorization?: ApplicationSpatialReviewAuthorization;
82
88
  readonly hostResourceLease?: ApplicationHostResourceLease;
83
89
  readonly htmlOverlayRenderer?: HtmlOverlayRenderer;
84
90
  /** Per-user host state shared by repository worktrees for mutation leases. */
@@ -45,7 +45,20 @@ import {
45
45
  spatialInspectOperationDefinition,
46
46
  spatialPatchOperationDefinition,
47
47
  spatialEvaluateOperationDefinition,
48
+ spatialAuditOperationDefinition,
49
+ spatialDirectionCheckOperationDefinition,
50
+ spatialDirectionCompileOperationDefinition,
51
+ spatialDirectionGalleryOperationDefinition,
52
+ spatialEffectsCheckOperationDefinition,
53
+ spatialEffectsPlanOperationDefinition,
54
+ spatialBehaviorCheckOperationDefinition,
55
+ spatialBehaviorBakeOperationDefinition,
56
+ spatialBehaviorGalleryOperationDefinition,
57
+ spatialBehaviorAuditOperationDefinition,
58
+ spatialTemporalAuditOperationDefinition,
48
59
  spatialRenderOperationDefinition,
60
+ spatialRenderedAuditOperationDefinition,
61
+ spatialReviewOperationDefinition,
49
62
  studioRunOperationDefinition,
50
63
  spatialProjectSnapshotOperationDefinition,
51
64
  spatialProjectMigrateOperationDefinition,
@@ -75,7 +88,20 @@ export function createApplicationOperationRegistry(
75
88
  registry.register(spatialInspectOperationDefinition);
76
89
  registry.register(spatialPatchOperationDefinition);
77
90
  registry.register(spatialEvaluateOperationDefinition);
91
+ registry.register(spatialAuditOperationDefinition);
92
+ registry.register(spatialDirectionCheckOperationDefinition);
93
+ registry.register(spatialDirectionCompileOperationDefinition);
94
+ registry.register(spatialDirectionGalleryOperationDefinition);
95
+ registry.register(spatialEffectsCheckOperationDefinition);
96
+ registry.register(spatialEffectsPlanOperationDefinition);
97
+ registry.register(spatialBehaviorCheckOperationDefinition);
98
+ registry.register(spatialBehaviorBakeOperationDefinition);
99
+ registry.register(spatialBehaviorGalleryOperationDefinition);
100
+ registry.register(spatialBehaviorAuditOperationDefinition);
101
+ registry.register(spatialTemporalAuditOperationDefinition);
78
102
  registry.register(spatialRenderOperationDefinition);
103
+ registry.register(spatialRenderedAuditOperationDefinition);
104
+ registry.register(spatialReviewOperationDefinition);
79
105
  registry.register(studioRunOperationDefinition);
80
106
  registry.register(spatialProjectSnapshotOperationDefinition);
81
107
  registry.register(spatialProjectMigrateOperationDefinition);
@@ -4,13 +4,26 @@ import type { z } from "zod";
4
4
 
5
5
  import type { ApplicationContext } from "./context";
6
6
 
7
- export const SLOPCAMERA_APPLICATION_TOOL_VERSION = "slopcamera-3.2.8" as const;
7
+ export const SLOPCAMERA_APPLICATION_TOOL_VERSION = "slopcamera-3.3.1" as const;
8
8
 
9
9
  export const OPERATION_KINDS = [
10
+ "scene.audit",
10
11
  "scene.inspect",
11
12
  "scene.patch",
12
13
  "scene.evaluate",
13
14
  "scene.render",
15
+ "scene.render-audit",
16
+ "scene.review",
17
+ "scene.direction.check",
18
+ "scene.direction.compile",
19
+ "scene.direction.gallery",
20
+ "scene.effects.check",
21
+ "scene.effects.plan",
22
+ "scene.behavior.check",
23
+ "scene.behavior.bake",
24
+ "scene.behavior.gallery",
25
+ "scene.behavior.audit",
26
+ "scene.temporal-audit",
14
27
  "slopcamera.studio.run",
15
28
  "spatial.project.snapshot",
16
29
  "spatial.project.migrate",
@@ -23,8 +23,12 @@ export * from "./render/project-plan";
23
23
  export * from "./render/project";
24
24
  export * from "./render/materialize-selection";
25
25
  export * from "./slopcamera-visuals";
26
+ export * from "./spatial-behavior";
27
+ export * from "./spatial-direction";
26
28
  export * from "./spatial-scene";
27
29
  export * from "./spatial-project";
28
30
  export * from "./spatial-render";
31
+ export * from "./spatial-rendered-audit";
32
+ export * from "./spatial-review";
29
33
 
30
34
  export * from "./studio";
@@ -0,0 +1,151 @@
1
+ import { z } from "zod";
2
+ import { createBoundedJsonValueSnapshot } from "../../../../src/code/json-snapshot";
3
+ import {
4
+ SpatialDigestSchema,
5
+ SpatialSceneV1Schema,
6
+ SpatialTimeUsSchema,
7
+ } from "../../../../src/spatial-scene/contracts";
8
+ import {
9
+ checkSpatialBehavior,
10
+ SpatialBehaviorCheckReportSchema,
11
+ SpatialBehaviorSchema,
12
+ } from "../../../../src/spatial-scene/behavior";
13
+ import {
14
+ auditSpatialBehaviorTrace,
15
+ SpatialBehaviorAuditOptionsSchema,
16
+ SpatialBehaviorAuditReportSchema,
17
+ } from "../../../../src/spatial-scene/behavior-audit";
18
+ import { bakeSpatialBehavior } from "../../../../src/spatial-scene/behavior-bake";
19
+ import { spatialBehaviorFnSignatures } from "../../../../src/spatial-scene/behavior-fns";
20
+ import {
21
+ planSpatialBehaviorGallery,
22
+ SpatialBehaviorGalleryPlanSchema,
23
+ } from "../../../../src/spatial-scene/behavior-gallery";
24
+ import {
25
+ SpatialBehaviorBakeSchema,
26
+ SpatialBehaviorChannelMapSchema,
27
+ SpatialBehaviorEmittedSchema,
28
+ } from "../../../../src/spatial-scene/behavior-trace";
29
+ import type { OperationDefinition, OperationPolicy } from "../operation";
30
+ import { throwIfAborted } from "./shared";
31
+
32
+ const capture = (value: unknown) => createBoundedJsonValueSnapshot(
33
+ value,
34
+ 8 * 1024 * 1024,
35
+ "behavior operation",
36
+ { maximumDepth: 36, maximumValues: 400_000 },
37
+ ).value;
38
+
39
+ export const SpatialBehaviorCheckInputSchema = z.preprocess(capture, z.strictObject({
40
+ behavior: SpatialBehaviorSchema,
41
+ scene: SpatialSceneV1Schema,
42
+ }));
43
+ export const SpatialBehaviorBakeInputSchema = z.preprocess(capture, z.strictObject({
44
+ behavior: SpatialBehaviorSchema,
45
+ channelMap: SpatialBehaviorChannelMapSchema.optional(),
46
+ scene: SpatialSceneV1Schema,
47
+ }));
48
+ export const SpatialBehaviorGalleryInputSchema = z.preprocess(capture, z.strictObject({
49
+ behavior: SpatialBehaviorSchema,
50
+ channelMap: SpatialBehaviorChannelMapSchema.optional(),
51
+ scene: SpatialSceneV1Schema,
52
+ }));
53
+
54
+ export const SpatialBehaviorAuditInputSchema = z.preprocess(capture, z.strictObject({
55
+ emitted: z.array(SpatialBehaviorEmittedSchema).max(16_384),
56
+ behaviorSha256: SpatialDigestSchema,
57
+ emittedSha256: SpatialDigestSchema,
58
+ rangeUs: z.strictObject({ startUs: SpatialTimeUsSchema, endUs: SpatialTimeUsSchema }),
59
+ options: SpatialBehaviorAuditOptionsSchema.optional(),
60
+ }));
61
+
62
+ export type SpatialBehaviorCheckInput = z.infer<typeof SpatialBehaviorCheckInputSchema>;
63
+ export type SpatialBehaviorBakeInput = z.infer<typeof SpatialBehaviorBakeInputSchema>;
64
+ export type SpatialBehaviorGalleryInput = z.infer<typeof SpatialBehaviorGalleryInputSchema>;
65
+ export type SpatialBehaviorAuditInput = z.infer<typeof SpatialBehaviorAuditInputSchema>;
66
+ export type SpatialBehaviorCheckOutput = z.infer<typeof SpatialBehaviorCheckReportSchema>;
67
+ export type SpatialBehaviorBakeOutput = z.infer<typeof SpatialBehaviorBakeSchema>;
68
+ export type SpatialBehaviorGalleryOutput = z.infer<typeof SpatialBehaviorGalleryPlanSchema>;
69
+ export type SpatialBehaviorAuditOutput = z.infer<typeof SpatialBehaviorAuditReportSchema>;
70
+
71
+ const purePolicy = Object.freeze({
72
+ cache: "content-addressed", cancellable: true, effect: "pure", maxDurationMs: 10_000,
73
+ maxFanOut: 0, maxInputBytes: 8 * 1024 * 1024, maxOutputBytes: 16 * 1024 * 1024,
74
+ preparation: [], resources: [{ amount: 1, resource: "cpu" }], resume: "deterministic",
75
+ } as const) satisfies OperationPolicy;
76
+
77
+ export const spatialBehaviorCheckOperationDefinition = {
78
+ kind: "scene.behavior.check", version: 1,
79
+ inputSchema: SpatialBehaviorCheckInputSchema,
80
+ inputSchemaId: "slopcamera.operation.scene.behavior.check.input/v1",
81
+ outputSchema: SpatialBehaviorCheckReportSchema,
82
+ outputSchemaId: "slopcamera.operation.scene.behavior.check.output/v1",
83
+ policy: purePolicy,
84
+ lifecycle: { kind: "pure", execute: (context, input) => {
85
+ throwIfAborted(context.abortSignal);
86
+ return Promise.resolve(SpatialBehaviorCheckReportSchema.parse(
87
+ checkSpatialBehavior({ behavior: input.behavior, scene: input.scene }, spatialBehaviorFnSignatures()),
88
+ ));
89
+ } },
90
+ summarize: output => ({ kind: "scene.behavior.check", fields: {
91
+ behaviorSha256: output.behaviorSha256, errors: output.counts.errors, warnings: output.counts.warnings,
92
+ } }),
93
+ } satisfies OperationDefinition<"scene.behavior.check", SpatialBehaviorCheckInput, SpatialBehaviorCheckOutput>;
94
+
95
+ export const spatialBehaviorBakeOperationDefinition = {
96
+ kind: "scene.behavior.bake", version: 1,
97
+ inputSchema: SpatialBehaviorBakeInputSchema,
98
+ inputSchemaId: "slopcamera.operation.scene.behavior.bake.input/v1",
99
+ outputSchema: SpatialBehaviorBakeSchema,
100
+ outputSchemaId: "slopcamera.operation.scene.behavior.bake.output/v1",
101
+ policy: purePolicy,
102
+ lifecycle: { kind: "pure", execute: async (context, input) => {
103
+ throwIfAborted(context.abortSignal);
104
+ const { bake } = await bakeSpatialBehavior({
105
+ behavior: input.behavior, scene: input.scene,
106
+ ...(input.channelMap === undefined ? {} : { channelMap: input.channelMap }),
107
+ });
108
+ return SpatialBehaviorBakeSchema.parse(bake);
109
+ } },
110
+ summarize: output => ({ kind: "scene.behavior.bake", fields: {
111
+ behaviorSha256: output.behaviorSha256, emitted: output.emitted.length,
112
+ directives: output.directives.length, unresolved: output.unresolvedIntents.length,
113
+ runDigest: output.receipt.runDigest,
114
+ } }),
115
+ } satisfies OperationDefinition<"scene.behavior.bake", SpatialBehaviorBakeInput, SpatialBehaviorBakeOutput>;
116
+
117
+ export const spatialBehaviorGalleryOperationDefinition = {
118
+ kind: "scene.behavior.gallery", version: 1,
119
+ inputSchema: SpatialBehaviorGalleryInputSchema,
120
+ inputSchemaId: "slopcamera.operation.scene.behavior.gallery.input/v1",
121
+ outputSchema: SpatialBehaviorGalleryPlanSchema,
122
+ outputSchemaId: "slopcamera.operation.scene.behavior.gallery.output/v1",
123
+ policy: purePolicy,
124
+ lifecycle: { kind: "pure", execute: async (context, input) => {
125
+ throwIfAborted(context.abortSignal);
126
+ return SpatialBehaviorGalleryPlanSchema.parse(await planSpatialBehaviorGallery({
127
+ behavior: input.behavior, scene: input.scene,
128
+ ...(input.channelMap === undefined ? {} : { channelMap: input.channelMap }),
129
+ }));
130
+ } },
131
+ summarize: output => ({ kind: "scene.behavior.gallery", fields: {
132
+ behaviorSha256: output.behaviorSha256, candidates: output.candidates.length,
133
+ } }),
134
+ } satisfies OperationDefinition<"scene.behavior.gallery", SpatialBehaviorGalleryInput, SpatialBehaviorGalleryOutput>;
135
+
136
+ export const spatialBehaviorAuditOperationDefinition = {
137
+ kind: "scene.behavior.audit", version: 1,
138
+ inputSchema: SpatialBehaviorAuditInputSchema,
139
+ inputSchemaId: "slopcamera.operation.scene.behavior.audit.input/v1",
140
+ outputSchema: SpatialBehaviorAuditReportSchema,
141
+ outputSchemaId: "slopcamera.operation.scene.behavior.audit.output/v1",
142
+ policy: purePolicy,
143
+ lifecycle: { kind: "pure", execute: (context, input) => {
144
+ throwIfAborted(context.abortSignal);
145
+ return Promise.resolve(SpatialBehaviorAuditReportSchema.parse(auditSpatialBehaviorTrace(input)));
146
+ } },
147
+ summarize: output => ({ kind: "scene.behavior.audit", fields: {
148
+ behaviorSha256: output.behaviorSha256, findings: output.findings.length,
149
+ channels: output.channelCount, emitted: output.emittedCount,
150
+ } }),
151
+ } satisfies OperationDefinition<"scene.behavior.audit", SpatialBehaviorAuditInput, SpatialBehaviorAuditOutput>;
@@ -0,0 +1,222 @@
1
+ import { z } from "zod";
2
+ import { createBoundedJsonValueSnapshot } from "../../../../src/code/json-snapshot";
3
+ import {
4
+ SpatialCameraIdSchema,
5
+ SpatialSceneV1Schema,
6
+ SpatialTimeUsSchema,
7
+ } from "../../../../src/spatial-scene/contracts";
8
+ import { SpatialDirectionSchema } from "../../../../src/spatial-scene/direction";
9
+ import {
10
+ checkSpatialDirection,
11
+ compileSpatialDirection,
12
+ SpatialDirectionCheckReportSchema,
13
+ SpatialDirectionCompilationSchema,
14
+ } from "../../../../src/spatial-scene/direction-compile";
15
+ import {
16
+ createSpatialEvaluationContext,
17
+ evaluateSpatialSceneInContext,
18
+ } from "../../../../src/spatial-scene/evaluate";
19
+ import {
20
+ planSpatialDirectionGallery,
21
+ SpatialGalleryAxisSchema,
22
+ SpatialGalleryPlanSchema,
23
+ } from "../../../../src/spatial-scene/gallery";
24
+ import { SpatialParticleSystemSchema } from "../../../../src/spatial-scene/particle";
25
+ import { SpatialRenderPlanSchema } from "../../../../src/spatial-scene/effects";
26
+ import {
27
+ checkSpatialRenderEffects,
28
+ planSpatialRenderEffects,
29
+ SPATIAL_RENDER_EFFECTS_LIMITS,
30
+ SpatialEffectsCheckReportSchema,
31
+ SpatialRenderEffectsBindingSchema,
32
+ SpatialRenderEffectsDocumentSchema,
33
+ } from "../../../../src/spatial-scene/render-effects";
34
+ import { SpatialSimulationBakeReceiptSchema } from "../../../../src/spatial-scene/simulation";
35
+ import {
36
+ auditSpatialTemporalEvidence,
37
+ SpatialTemporalAuditOptionsSchema,
38
+ SpatialTemporalAuditReportSchema,
39
+ } from "../../../../src/spatial-scene/temporal-audit";
40
+ import type { OperationDefinition, OperationPolicy } from "../operation";
41
+ import { throwIfAborted } from "./shared";
42
+
43
+ const capture = (value: unknown) => createBoundedJsonValueSnapshot(
44
+ value,
45
+ 8 * 1024 * 1024,
46
+ "scene planning operation",
47
+ { maximumDepth: 36, maximumValues: 400_000 },
48
+ ).value;
49
+
50
+ export const SpatialDirectionCheckInputSchema = z.preprocess(capture, z.strictObject({
51
+ direction: SpatialDirectionSchema,
52
+ scene: SpatialSceneV1Schema,
53
+ }));
54
+ export const SpatialDirectionCompileInputSchema = z.preprocess(capture, z.strictObject({
55
+ cameraId: SpatialCameraIdSchema.optional(),
56
+ direction: SpatialDirectionSchema,
57
+ scene: SpatialSceneV1Schema,
58
+ }));
59
+ export const SpatialDirectionGalleryInputSchema = z.preprocess(capture, z.strictObject({
60
+ axis: SpatialGalleryAxisSchema,
61
+ cameraId: SpatialCameraIdSchema.optional(),
62
+ direction: SpatialDirectionSchema,
63
+ scene: SpatialSceneV1Schema,
64
+ }));
65
+ export const SpatialEffectsCheckInputSchema = z.preprocess(capture, z.strictObject({
66
+ effects: z.union([SpatialRenderEffectsBindingSchema, SpatialRenderEffectsDocumentSchema]),
67
+ scene: SpatialSceneV1Schema,
68
+ }));
69
+ export const SpatialEffectsPlanInputSchema = z.preprocess(capture, z.strictObject({
70
+ particleSystems: z.array(SpatialParticleSystemSchema).max(SPATIAL_RENDER_EFFECTS_LIMITS.particleSystems).default([]),
71
+ renderPlan: SpatialRenderPlanSchema,
72
+ scene: SpatialSceneV1Schema,
73
+ simulationBakes: z.array(SpatialSimulationBakeReceiptSchema).max(SPATIAL_RENDER_EFFECTS_LIMITS.simulationBakes).default([]),
74
+ }));
75
+ export const SpatialTemporalAuditInputSchema = z.preprocess(capture, z.strictObject({
76
+ cameraId: SpatialCameraIdSchema,
77
+ options: SpatialTemporalAuditOptionsSchema.optional(),
78
+ scene: SpatialSceneV1Schema,
79
+ timesUs: z.array(SpatialTimeUsSchema).min(2).max(64).optional(),
80
+ }));
81
+ export type SpatialDirectionCheckInput = z.infer<typeof SpatialDirectionCheckInputSchema>;
82
+ export type SpatialDirectionCompileInput = z.infer<typeof SpatialDirectionCompileInputSchema>;
83
+ export type SpatialDirectionGalleryInput = z.infer<typeof SpatialDirectionGalleryInputSchema>;
84
+ export type SpatialEffectsCheckInput = z.infer<typeof SpatialEffectsCheckInputSchema>;
85
+ export type SpatialEffectsPlanInput = z.infer<typeof SpatialEffectsPlanInputSchema>;
86
+ export type SpatialTemporalAuditInput = z.infer<typeof SpatialTemporalAuditInputSchema>;
87
+ export type SpatialDirectionCheckOutput = z.infer<typeof SpatialDirectionCheckReportSchema>;
88
+ export type SpatialDirectionCompileOutput = z.infer<typeof SpatialDirectionCompilationSchema>;
89
+ export type SpatialDirectionGalleryOutput = z.infer<typeof SpatialGalleryPlanSchema>;
90
+ export type SpatialEffectsCheckOutput = z.infer<typeof SpatialEffectsCheckReportSchema>;
91
+ export type SpatialEffectsPlanOutput = z.infer<typeof SpatialRenderEffectsBindingSchema>;
92
+ export type SpatialTemporalAuditOutput = z.infer<typeof SpatialTemporalAuditReportSchema>;
93
+
94
+ const purePolicy = Object.freeze({
95
+ cache: "content-addressed", cancellable: true, effect: "pure", maxDurationMs: 10_000,
96
+ maxFanOut: 0, maxInputBytes: 8 * 1024 * 1024, maxOutputBytes: 16 * 1024 * 1024,
97
+ preparation: [], resources: [{ amount: 1, resource: "cpu" }], resume: "deterministic",
98
+ } as const) satisfies OperationPolicy;
99
+
100
+ const compileTimesUs = (input: SpatialTemporalAuditInput): readonly number[] => {
101
+ if (input.timesUs !== undefined) return [...input.timesUs].sort((left, right) => left - right);
102
+ const count = Math.min(17, Math.max(2, Math.ceil(input.scene.durationUs / 1_000_000) + 1));
103
+ return Array.from({ length: count }, (_, index) => Math.floor((input.scene.durationUs * index) / (count - 1)));
104
+ };
105
+
106
+ export const spatialDirectionCheckOperationDefinition = {
107
+ kind: "scene.direction.check", version: 1,
108
+ inputSchema: SpatialDirectionCheckInputSchema,
109
+ inputSchemaId: "slopcamera.operation.scene.direction.check.input/v1",
110
+ outputSchema: SpatialDirectionCheckReportSchema,
111
+ outputSchemaId: "slopcamera.operation.scene.direction.check.output/v1",
112
+ policy: purePolicy,
113
+ lifecycle: { kind: "pure", execute: (context, input) => {
114
+ throwIfAborted(context.abortSignal);
115
+ return Promise.resolve(SpatialDirectionCheckReportSchema.parse(
116
+ checkSpatialDirection({ direction: input.direction, scene: input.scene }),
117
+ ));
118
+ } },
119
+ summarize: output => ({ kind: "scene.direction.check", fields: {
120
+ directionSha256: output.directionSha256, errors: output.counts.errors, warnings: output.counts.warnings,
121
+ } }),
122
+ } satisfies OperationDefinition<"scene.direction.check", SpatialDirectionCheckInput, SpatialDirectionCheckOutput>;
123
+
124
+ export const spatialDirectionCompileOperationDefinition = {
125
+ kind: "scene.direction.compile", version: 1,
126
+ inputSchema: SpatialDirectionCompileInputSchema,
127
+ inputSchemaId: "slopcamera.operation.scene.direction.compile.input/v1",
128
+ outputSchema: SpatialDirectionCompilationSchema,
129
+ outputSchemaId: "slopcamera.operation.scene.direction.compile.output/v1",
130
+ policy: purePolicy,
131
+ lifecycle: { kind: "pure", execute: (context, input) => {
132
+ throwIfAborted(context.abortSignal);
133
+ return Promise.resolve(SpatialDirectionCompilationSchema.parse(compileSpatialDirection({
134
+ direction: input.direction, scene: input.scene,
135
+ ...(input.cameraId === undefined ? {} : { cameraId: input.cameraId }),
136
+ })));
137
+ } },
138
+ summarize: output => ({ kind: "scene.direction.compile", fields: {
139
+ sceneSha256: output.sceneSha256, shots: output.proposals.shots.length,
140
+ unresolved: output.unresolvedIntents.length, advisories: output.advisories.length,
141
+ } }),
142
+ } satisfies OperationDefinition<"scene.direction.compile", SpatialDirectionCompileInput, SpatialDirectionCompileOutput>;
143
+
144
+ export const spatialDirectionGalleryOperationDefinition = {
145
+ kind: "scene.direction.gallery", version: 1,
146
+ inputSchema: SpatialDirectionGalleryInputSchema,
147
+ inputSchemaId: "slopcamera.operation.scene.direction.gallery.input/v1",
148
+ outputSchema: SpatialGalleryPlanSchema,
149
+ outputSchemaId: "slopcamera.operation.scene.direction.gallery.output/v1",
150
+ policy: purePolicy,
151
+ lifecycle: { kind: "pure", execute: (context, input) => {
152
+ throwIfAborted(context.abortSignal);
153
+ return Promise.resolve(SpatialGalleryPlanSchema.parse(planSpatialDirectionGallery({
154
+ axis: input.axis, direction: input.direction, scene: input.scene,
155
+ ...(input.cameraId === undefined ? {} : { cameraId: input.cameraId }),
156
+ })));
157
+ } },
158
+ summarize: output => ({ kind: "scene.direction.gallery", fields: {
159
+ axis: output.axis, candidates: output.candidates.length, sourceSha256: output.sourceSha256,
160
+ } }),
161
+ } satisfies OperationDefinition<"scene.direction.gallery", SpatialDirectionGalleryInput, SpatialDirectionGalleryOutput>;
162
+
163
+ export const spatialEffectsCheckOperationDefinition = {
164
+ kind: "scene.effects.check", version: 1,
165
+ inputSchema: SpatialEffectsCheckInputSchema,
166
+ inputSchemaId: "slopcamera.operation.scene.effects.check.input/v1",
167
+ outputSchema: SpatialEffectsCheckReportSchema,
168
+ outputSchemaId: "slopcamera.operation.scene.effects.check.output/v1",
169
+ policy: purePolicy,
170
+ lifecycle: { kind: "pure", execute: (context, input) => {
171
+ throwIfAborted(context.abortSignal);
172
+ return Promise.resolve(SpatialEffectsCheckReportSchema.parse(
173
+ checkSpatialRenderEffects({ effects: input.effects, scene: input.scene }),
174
+ ));
175
+ } },
176
+ summarize: output => ({ kind: "scene.effects.check", fields: {
177
+ errors: output.counts.errors, warnings: output.counts.warnings, sceneSha256: output.sceneSha256,
178
+ } }),
179
+ } satisfies OperationDefinition<"scene.effects.check", SpatialEffectsCheckInput, SpatialEffectsCheckOutput>;
180
+
181
+ export const spatialEffectsPlanOperationDefinition = {
182
+ kind: "scene.effects.plan", version: 1,
183
+ inputSchema: SpatialEffectsPlanInputSchema,
184
+ inputSchemaId: "slopcamera.operation.scene.effects.plan.input/v1",
185
+ outputSchema: SpatialRenderEffectsBindingSchema,
186
+ outputSchemaId: "slopcamera.operation.scene.effects.plan.output/v1",
187
+ policy: purePolicy,
188
+ lifecycle: { kind: "pure", execute: (context, input) => {
189
+ throwIfAborted(context.abortSignal);
190
+ return Promise.resolve(SpatialRenderEffectsBindingSchema.parse(planSpatialRenderEffects({
191
+ particleSystems: input.particleSystems, renderPlan: input.renderPlan, scene: input.scene,
192
+ simulationBakes: input.simulationBakes,
193
+ })));
194
+ } },
195
+ summarize: output => ({ kind: "scene.effects.plan", fields: {
196
+ documentSha256: output.documentSha256, renderPlanSha256: output.document.renderPlanSha256,
197
+ } }),
198
+ } satisfies OperationDefinition<"scene.effects.plan", SpatialEffectsPlanInput, SpatialEffectsPlanOutput>;
199
+
200
+ export const spatialTemporalAuditOperationDefinition = {
201
+ kind: "scene.temporal-audit", version: 1,
202
+ inputSchema: SpatialTemporalAuditInputSchema,
203
+ inputSchemaId: "slopcamera.operation.scene.temporal-audit.input/v1",
204
+ outputSchema: SpatialTemporalAuditReportSchema,
205
+ outputSchemaId: "slopcamera.operation.scene.temporal-audit.output/v1",
206
+ policy: purePolicy,
207
+ lifecycle: { kind: "pure", execute: (context, input) => {
208
+ throwIfAborted(context.abortSignal);
209
+ const evaluationContext = createSpatialEvaluationContext(input.scene);
210
+ const snapshots = compileTimesUs(input).map(timeUs =>
211
+ evaluateSpatialSceneInContext(evaluationContext, { cameraId: input.cameraId, timeUs }));
212
+ return Promise.resolve(SpatialTemporalAuditReportSchema.parse(
213
+ auditSpatialTemporalEvidence({
214
+ snapshots,
215
+ ...(input.options === undefined ? {} : { options: input.options }),
216
+ }),
217
+ ));
218
+ } },
219
+ summarize: output => ({ kind: "scene.temporal-audit", fields: {
220
+ findings: output.findings.length, samples: output.sampleCount, sceneSha256: output.sceneSha256,
221
+ } }),
222
+ } satisfies OperationDefinition<"scene.temporal-audit", SpatialTemporalAuditInput, SpatialTemporalAuditOutput>;