@robmclarty/volley 0.5.4 → 0.6.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.
package/dist/index.d.ts CHANGED
@@ -276,8 +276,8 @@ type ResolveOptions = {
276
276
  env?: Record<string, string | undefined>;
277
277
  };
278
278
  /** Merge, expand, and validate a raw `VolleyConfig` into a `ResolvedConfig`.
279
- * `check_resolved` is filled in later by check detection (workspace-relative);
280
- * it starts as `none` and `resolve_check_runner` overrides it. */
279
+ * `check_resolved` comes from check detection against the workspace, so the
280
+ * SDK and the CLI resolve `auto` and a command check the same way. */
281
281
  declare function resolve_config(raw: VolleyConfig, options?: ResolveOptions): ResolvedConfig;
282
282
 
283
283
  type Role = 'builder' | 'critic' | 'check';
@@ -349,6 +349,89 @@ declare const verdict_schema: z.ZodObject<{
349
349
  }, z.core.$strip>;
350
350
  type VerdictOutput = z.infer<typeof verdict_schema>;
351
351
 
352
+ /** Canonical identity of the allowlist bridge the examples create (`docker
353
+ * network create --subnet <SANDBOX_NETWORK_SUBNET> <SANDBOX_NETWORK_NAME>`) and
354
+ * the host `DOCKER-USER` rules scope to. Exported so the blessed examples
355
+ * share one spelling of the invocation spec. */
356
+ declare const SANDBOX_NETWORK_NAME = "volley-sandbox-net";
357
+ declare const SANDBOX_NETWORK_SUBNET = "172.31.99.0/24";
358
+ /**
359
+ * The container's egress posture. Under whole-process containment
360
+ * the model client and the `fetch` tool run inside the container, so its
361
+ * legitimate egress is the package registry for `pnpm install` plus the host LLM
362
+ * endpoint the model client reaches via host-gateway.
363
+ *
364
+ * - `'none'` — `--network none`: no interface at all, a complete L3 egress deny.
365
+ * The default-deny default; it fits a genuinely offline run where the model and
366
+ * deps are already in-container (a host-run model is unreachable under `none`).
367
+ * With the whole process in-container, `fetch` has no route either, so it
368
+ * degrades cleanly to a returned error result and the run continues.
369
+ * - `'allowlist'` — the container sits on volley's dedicated user-defined bridge
370
+ * with `host.docker.internal:host-gateway`, collapsing the allowlist targets
371
+ * (the package registry, and the host LLM endpoint the in-container model
372
+ * client now reaches) onto the host gateway. The L3/L4 default-DROP that
373
+ * makes the bridge a true allowlist is the host-applied, subnet-scoped
374
+ * `DOCKER-USER` rule the operator installs (volley never installs it — that
375
+ * chain is root and host-global, and on Docker Desktop lives inside a VM). The
376
+ * always-on tool-level SSRF deny-list is the second, in-process defense-in-depth
377
+ * layer. Host hardening, run once as root on a Linux host, scoped to volley's
378
+ * subnet so it never touches other containers (insert ahead of the chain's
379
+ * terminating RETURN, in order):
380
+ * iptables -I DOCKER-USER -s 172.31.99.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
381
+ * iptables -I DOCKER-USER -s 172.31.99.0/24 -d <host-gateway-ip> -j ACCEPT # collapsed allowlist
382
+ * iptables -I DOCKER-USER -s 172.31.99.0/24 -p udp --dport 53 -j ACCEPT # DNS
383
+ * iptables -I DOCKER-USER -s 172.31.99.0/24 -j DROP # default-deny the rest
384
+ */
385
+ type SandboxNetwork = 'none' | 'allowlist';
386
+ /**
387
+ * The network-related `docker run` args for a posture, pure and exported
388
+ * so the policy is unit-testable without a daemon. `'none'` denies all egress
389
+ * (`--network none`); `'allowlist'` attaches the dedicated user-defined bridge and
390
+ * collapses the allowlist targets onto the host gateway (`host.docker.internal`,
391
+ * the Linux-portable spelling — harmless where Docker Desktop already provides it).
392
+ */
393
+ declare function network_run_args(network: SandboxNetwork, network_name: string): string[];
394
+ /**
395
+ * The hardened `docker run` argv that launches volley inside its container.
396
+ * Pure and exported so the flag set is unit-testable without a
397
+ * daemon and the blessed examples / `--dry-run` preflight can render it.
398
+ *
399
+ * A one-shot, foreground `--rm` container — the whole run *is* this
400
+ * container (an earlier design ran a detached `-d … sleep infinity` daemon volley
401
+ * `exec`'d against), so `--rm` cleans it up when volley exits. `command`
402
+ * appends the container command (the volley args); omit it to use the image's
403
+ * `volley` entrypoint. `env` injects `-e KEY=VALUE` pairs (the `VOLLEY_MODEL_HOST`
404
+ * crossing). `labels` adds `--label KEY=VALUE` pairs, so a caller that owns the
405
+ * container's lifecycle can find and reap it by label. `entrypoint` overrides
406
+ * the image entrypoint (the opt-in real-docker isolation test runs a raw `sh`
407
+ * this way).
408
+ *
409
+ * `store_volume` mounts the named volume as the pnpm store; omit it and no store
410
+ * is mounted. A store is shared by every run that mounts it, so a caller that
411
+ * installs dependencies in a separate container first can keep the builder's
412
+ * container off it, and no builder can leave files in a store a later install
413
+ * trusts.
414
+ *
415
+ * Never emits `--privileged` and refuses `--user 0`: volley must not hand
416
+ * the sandbox root or full capabilities. Everything writable under the
417
+ * `--read-only` rootfs is an explicit tmpfs or volume; the bind-mounted worktree
418
+ * is the one host-visible write path.
419
+ */
420
+ declare function sandbox_run_args(options: {
421
+ image: string;
422
+ build_root: string;
423
+ uid: number | null;
424
+ gid: number | null;
425
+ store_volume?: string | null;
426
+ network: SandboxNetwork;
427
+ network_name: string;
428
+ name?: string | null;
429
+ env?: ReadonlyArray<readonly [string, string]>;
430
+ labels?: ReadonlyArray<readonly [string, string]>;
431
+ entrypoint?: string | null;
432
+ command?: ReadonlyArray<string>;
433
+ }): string[];
434
+
352
435
  declare const EXIT_SUCCESS = 0;
353
436
  declare const EXIT_BUDGET_EXHAUSTED = 2;
354
437
  declare const EXIT_BUILDER_ERROR = 3;
@@ -360,4 +443,4 @@ declare const EXIT_INTERRUPTED = 130;
360
443
  declare function exit_code_for_status(status: RunStatus): number;
361
444
  declare function exit_code_for_error(err: unknown): number;
362
445
 
363
- export { type BuilderPermissionMode, type CheckArtifact, type CheckMode, type CheckResult, type CheckRunnerKind, type CostSource, type CriticPreset, type CriticProvider, EXIT_BUDGET_EXHAUSTED, EXIT_BUILDER_ERROR, EXIT_CHECK_ERROR, EXIT_CONFIG_ERROR, EXIT_COST_CAP, EXIT_CRITIC_ERROR, EXIT_INTERRUPTED, EXIT_SUCCESS, type HaltReason, type LoopState, type PhaseRecord, type RenderMode, type Renderer, type RendererOptions, type ResolvedConfig, type RunResult, type RunStatus, type Verdict, type VerdictOutput, type VolleyConfig, create_renderer, exit_code_for_error, exit_code_for_status, expand_at_file, gate, initial_state, load_config_file, resolve_config, run_volley, status_of, verdict_schema };
446
+ export { type BuilderPermissionMode, type CheckArtifact, type CheckMode, type CheckResult, type CheckRunnerKind, type CostSource, type CriticPreset, type CriticProvider, EXIT_BUDGET_EXHAUSTED, EXIT_BUILDER_ERROR, EXIT_CHECK_ERROR, EXIT_CONFIG_ERROR, EXIT_COST_CAP, EXIT_CRITIC_ERROR, EXIT_INTERRUPTED, EXIT_SUCCESS, type HaltReason, type LoopState, type PhaseRecord, type RenderMode, type Renderer, type RendererOptions, type ResolvedConfig, type RunResult, type RunStatus, SANDBOX_NETWORK_NAME, SANDBOX_NETWORK_SUBNET, type SandboxNetwork, type Verdict, type VerdictOutput, type VolleyConfig, create_renderer, exit_code_for_error, exit_code_for_status, expand_at_file, gate, initial_state, load_config_file, network_run_args, resolve_config, run_volley, sandbox_run_args, status_of, verdict_schema };