Skip to content

Wave 9: sdk - #11

Merged
ThePlenkov merged 12 commits into
wave-8-policyfrom
wave-9-sdk
Aug 11, 2026
Merged

ThePlenkov merged 12 commits into
wave-8-policyfrom
wave-9-sdk

Conversation

@ThePlenkov

@ThePlenkov ThePlenkov commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

User description

Summary

  • SDK composition root: re-exports from core, ir, runtime, runtime-host, runtime-docker, findings, policy
  • High-level API: createSverka(), discover(), plan(), execute(), evaluate()
  • Config file discovery (sverka.config.ts)
  • 60 tests pass (10 files)
  • Reviewer APPROVED with 5 non-blocking nits

Test plan

  • bun run test (sdk: 60 tests, full monorepo 16 projects green)
  • bun run typecheck (clean)
  • bun run build (green, dist index.mjs + index.d.mts)
  • bun run lint (clean)
  • reviewer approved (sv-3yy)

Stacked on #10

Generated with Devin


Summary by cubic

Adds @sverka/sdk as a single entry point to define, plan, and run workflows end-to-end. Includes config discovery, deterministic plan generation, host-first execution (Docker opt-in), baseline filtering, policy evaluation, and a typed SdkError. Findings are stubbed to [] until check providers land.

  • New Features

    • High-level API: createSverka(), plan(), execute(), defineWorkflow(), task(); config via findConfig() and loadWorkflow() (safe dynamic import with project-root guard).
    • Plan mode: side-effect-free plan runtime; convertToPlan() sets metadata (apiVersion, sverkaVersion from package.json, generatedBy, canonical sourceContextHash); deterministic computePlanId; zero-config plan() returns a proposal when no config is found.
    • Execution + Policy: host executor by default (Docker opt-in); returns status, outcomes, duration, verdict; baseline filtering via loadBaseline/filterOnlyNew; evaluates policy; findings stay empty for now.
    • Re-exports: core, IR (validatePlan, computePlanId), planner, runtime (Scheduler, @sverka/runtime-host, @sverka/runtime-docker), findings, policy.
  • Bug Fixes and Refactors

    • IR/source context: allow empty sourceContextHash; canonical stringify with sorted paths (explicit comparator).
    • Reliability: clamp retries to maxAttempts >= 1; 128-bit cache key; validate configPath is inside the project root; clean temp artifact/cache dirs with top-level try/finally; pass baseline fingerprints when baselinePath is set; derive Docker runAs from current uid/gid; forward PATH to the host executor.
    • Code health: reduced defaulting complexity (extracted resolveDefaults, explicit field mapping).
    • Build: ESM outputs (index.mjs, index.d.mts); derive sverkaVersion at runtime from package.json.

Written for commit c47f227. Summary will update on new commits.

Review in cubic


CodeAnt-AI Description

Add a single SDK entry point for defining, planning, and running workflows

What Changed

  • Added @sverka/sdk as a unified import for workflow building, project discovery, planning, execution, findings, and policy evaluation
  • Added plan() and execute() APIs, plus createSverka() for reusable defaults; planning records workflows without running commands
  • Added sverka.config.ts and .js discovery, workflow loading, validation, and clear typed errors for missing, invalid, or unloadable configuration
  • Added host execution by default with optional Docker execution, operation outcomes, execution status, policy verdicts, and baseline filtering support
  • Added deterministic plan generation with resource, timeout, retry, network, artifact, executor, and dependency defaults
  • Added workflow helpers, core package re-exports, and coverage for configuration, planning, execution, conversion, defaults, and error handling

Impact

✅ One import for end-to-end workflow use
✅ No command execution during planning
✅ Clear configuration failure errors

🔄 Retrigger CodeAnt AI Review

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai

codeant-ai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 17a50ba Aug 11, 2026 · 08:44 08:45
✅ Incremental review completed 6e01372 Aug 11, 2026 · 06:24 06:24
✅ Incremental review completed 05f6968 Aug 11, 2026 · 00:49 00:50
✅ Incremental review completed c43c604 Aug 10, 2026 · 20:19 20:20
✅ Reviewed your PR be628cf Aug 10, 2026 · 03:09 03:13

@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added a TypeScript SDK for discovering workflows, planning operations, and executing them on host or Docker runtimes.
    • Added public APIs for workflow definition, task naming, configuration loading, plan generation, and execution.
    • Added structured SDK errors with categorized configuration and execution codes.
    • Added execution results with status, operation outcomes, findings, policy verdicts, and duration.
  • Bug Fixes

    • Source context validation now accepts empty string values.
  • Documentation

    • Added comprehensive SDK architecture and implementation planning documentation.

Walkthrough

The PR adds the Wave 09 TypeScript SDK. It supports workflow discovery, plan mode, host or Docker execution, IR plan conversion, policy and baseline processing, structured results, typed errors, public exports, and comprehensive tests.

Changes

SDK facade implementation

Layer / File(s) Summary
SDK contracts and workspace integration
engdocs/architecture/wave-09-sdk-plan.md, specs/09-sdk/spec.md, packages/sdk/package.json, packages/sdk/project.json, packages/ir/src/validate.ts
Defines the plan/execute SDK contract, workspace integration, runtime dependencies, conversion defaults, and relaxed empty source-context hash validation.
Public API and configuration loading
packages/sdk/src/types.ts, packages/sdk/src/errors.ts, packages/sdk/src/index.ts, packages/sdk/src/config.ts, packages/sdk/src/__tests__/*
Adds SDK types, SdkError, public re-exports, task, defineWorkflow, configuration discovery, dynamic loading, shape validation, and related tests.
Plan runtime and IR conversion
packages/sdk/src/internal/plan-runtime.ts, packages/sdk/src/convert.ts, packages/sdk/src/__tests__/convert.test.ts, packages/sdk/src/__tests__/plan-mode.test.ts
Records operations in plan mode and converts them into validated IR plans with execution defaults, dependencies, hashes, artifacts, caches, and executor metadata.
Execution orchestration and result processing
packages/sdk/src/sverka.ts, packages/sdk/src/__tests__/execute-mode.test.ts
Adds configured and top-level planning and execution, executor selection, scheduler integration, temporary resource management, baseline filtering, policy evaluation, verdicts, and structured outcomes.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Sverka
  participant ConfigLoader
  participant PlanRuntime
  participant PlanConverter
  participant Scheduler
  participant PolicyEvaluator
  Sverka->>ConfigLoader: discover and load workflow
  Sverka->>PlanRuntime: evaluate workflow operations
  Sverka->>PlanConverter: convert operations into validated plan
  Sverka->>Scheduler: execute plan with selected executor
  Scheduler-->>Sverka: return status and outcomes
  Sverka->>PolicyEvaluator: evaluate findings and baseline result
  PolicyEvaluator-->>Sverka: return policy result and verdict
Loading

Possibly related PRs

  • sverka-dev/sverka#1: Provides the core workflow, operation, runtime, and planning APIs used by the SDK.
  • sverka-dev/sverka#2: Provides the IR plan schema, validation, deterministic IDs, and source-context hash behavior.
  • sverka-dev/sverka#3: Provides the scheduler, executor contracts, and execution results used by SDK execution.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title identifies the Wave 9 SDK change and is concise enough for the main implementation objective.
Description check ✅ Passed The description directly explains the SDK APIs, configuration, planning, execution, testing, and related implementation changes.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch wave-9-sdk

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Aug 10, 2026

@amazon-q-developer amazon-q-developer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR implements the SDK layer with comprehensive re-exports, high-level APIs, and config discovery. The implementation is generally well-structured, but several critical issues must be addressed before merge:

Critical Issues (5 findings):

  1. Security: Unrestricted command allowlist creates code execution risk when loading untrusted configs
  2. Security: Path traversal vulnerability in config loading without path validation
  3. Security: Truncated hash in cache key generation increases collision risk
  4. Logic: Missing cleanup of temporary directories in failure scenarios
  5. Logic: Unsafe type assertion bypasses TypeScript's type safety

Strengths:

  • Clean API design with createSverka factory pattern
  • Comprehensive re-exports from core packages
  • Good separation of plan vs execute modes
  • Extensive test coverage (60 tests passing)

All findings require fixes as they either create security vulnerabilities or logic errors that could cause incorrect behavior or resource leaks.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Comment thread packages/sdk/src/sverka.ts
Comment thread packages/sdk/src/sverka.ts
Comment thread packages/sdk/src/sverka.ts Outdated
Comment thread packages/sdk/src/config.ts
Comment thread packages/sdk/src/convert.ts
@codacy-production

codacy-production Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 111 complexity · 4 duplication

Metric Results
Complexity 111
Duplication 4

View in Codacy

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@baz-reviewer

baz-reviewer Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Merger

Needs Review

PR exceeds the merge-gate context budget (72597 tokens); escalating to a human reviewer.

Commit c47f227 · Evaluated 2026-08-11 16:09 UTC

Review this PR on Baz | Customize your next review

@baz-reviewer

baz-reviewer Bot commented Aug 10, 2026

Copy link
Copy Markdown

Merger

Needs Review

This non-trivial public SDK/runtime change has no CI verification. The SDK tests dynamically import @sverka/sdk, whose package exports point to dist/index.mjs, but the test target does not build the package and no dist output is present, so clean test execution is uncertain.

Commit be628cf · Evaluated 2026-08-10 03:11 UTC


Review this PR on Baz | Customize your next review

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add @sverka/sdk public API with config discovery, plan(), and execute()

✨ Enhancement 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Introduce @sverka/sdk composition root with re-exports and plan/execute APIs.
• Add sverka.config.{ts,js} discovery/loading and workflow → IR Plan conversion.
• Add vitest suite covering public API, config errors, plan mode, and execution mode.
Diagram

graph TD
U["SDK consumer"] --> SDK["@sverka/sdk"] --> CFG["findConfig/loadWorkflow"] --> EVAL["PlanRuntime eval"] --> CONV["convertToPlan"] --> RT["Scheduler+Executor"] --> POL["Baseline+Policy"]
SDK --> PLNR["Planner discover/plan"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Make executor injection first-class
  • ➕ Allows custom executors and easier unit testing without running commands
  • ➕ Avoids hard-coding allowlist and Docker defaults in the SDK
  • ➖ Bigger surface area for v1; more docs and validation needed
  • ➖ Still need sensible defaults for typical users
2. Strict Workflow-only config (no bare Operation)
  • ➕ Simplifies config validation and normalization logic
  • ➕ Avoids ambiguity in config authoring
  • ➖ Less ergonomic for simple pipelines
  • ➖ Breaks the goal of allowing minimal configs (pipeline(...) directly)
3. Plan/execute return the IR Plan (or persist it)
  • ➕ Improves debuggability and allows external tooling to reuse the plan
  • ➕ Enables caching/replay/resume workflows later
  • ➖ Exposes more internal IR details to end users
  • ➖ Adds complexity to result types and backwards-compat constraints

Recommendation: The PR’s approach is appropriate for an initial SDK: keep the API small, make the SDK the single composition root, and wire execution end-to-end even with stubbed findings. Consider adding optional executor injection later (non-breaking) once real check providers land and testing needs expand.

Files changed (23) +2230 / -328

Enhancement (7) +743 / -0
config.tsImplement config discovery and dynamic workflow loading +99/-0

Implement config discovery and dynamic workflow loading

• Implements findConfig() searching for sverka.config.ts/js up to 5 parents and loadWorkflow() using dynamic import with shape validation and SdkError wrapping.

packages/sdk/src/config.ts

convert.tsImplement OperationSpec[] → IR Plan conversion with defaults +150/-0

Implement OperationSpec[] → IR Plan conversion with defaults

• Adds convertToPlan() to map core OperationSpec into IR Plan/PlanOperation, computing plan id, sourceContextHash, cache keys, and filling required defaults for execution.

packages/sdk/src/convert.ts

errors.tsAdd SDK-specific SdkError and error codes +20/-0

Add SDK-specific SdkError and error codes

• Defines SdkError with typed codes and optional cause to standardize config/execution error reporting across SDK entrypoints.

packages/sdk/src/errors.ts

index.tsDefine SDK public API surface and re-export hub +108/-0

Define SDK public API surface and re-export hub

• Creates the SDK composition root entrypoint: re-exports from core/ir/planner/runtime/findings/policy and exposes SDK helpers (task, defineWorkflow), config utilities, and plan/execute functions.

packages/sdk/src/index.ts

plan-runtime.tsAdd plan-mode Runtime that records operations +39/-0

Add plan-mode Runtime that records operations

• Introduces PlanRuntime implementing Runtime to evaluate workflow graphs without side effects by recording OperationSpec entries and returning planned outcomes.

packages/sdk/src/internal/plan-runtime.ts

sverka.tsImplement createSverka(), plan(), and execute() orchestration +261/-0

Implement createSverka(), plan(), and execute() orchestration

• Wires planner discovery, config resolution, workflow evaluation, plan conversion, optional plan validation, and runtime execution via Scheduler with HostExecutor/DockerExecutor; stubs findings and applies baseline+policy evaluation.

packages/sdk/src/sverka.ts

types.tsAdd SDK public types for options and result shapes +66/-0

Add SDK public types for options and result shapes

• Defines WorkflowDefinition, SverkaOptions, Sverka instance interface, and PlanResult/ExecutionResult types, including outcomes map and execution status.

packages/sdk/src/types.ts

Tests (11) +872 / -0
convert.test.tsAdd tests for OperationSpec[] → Plan conversion defaults +128/-0

Add tests for OperationSpec[] → Plan conversion defaults

• Verifies convertToPlan produces a validatePlan()-passing Plan, fills required defaults (resources, retry, network, timeout, artifacts), preserves dependencies, and produces deterministic computePlanId.

packages/sdk/src/tests/convert.test.ts

define-workflow.test.tsAdd tests for defineWorkflow identity helper +32/-0

Add tests for defineWorkflow identity helper

• Ensures defineWorkflow returns the same object and preserves required and optional fields like policy config.

packages/sdk/src/tests/define-workflow.test.ts

errors.test.tsAdd tests for SDK error codes and default options behavior +93/-0

Add tests for SDK error codes and default options behavior

• Covers CONFIG_INVALID/CONFIG_LOAD_FAILED/CONFIG_NOT_FOUND behaviors and verifies createSverka default options persist while per-call options override.

packages/sdk/src/tests/errors.test.ts

execute-mode.test.tsAdd execute() integration tests (host executor) +75/-0

Add execute() integration tests (host executor)

• Validates execute() returns status/verdict/outcomes, stubs findings as empty, and that createSverka().execute matches the top-level execute() behavior.

packages/sdk/src/tests/execute-mode.test.ts

find-config.test.tsAdd tests for sverka.config discovery rules +63/-0

Add tests for sverka.config discovery rules

• Tests upward search (max 5 parents), .ts preference, .js fallback, and null result when no config is found.

packages/sdk/src/tests/find-config.test.ts

fixtures.tsAdd temp filesystem/git fixtures for SDK tests +123/-0

Add temp filesystem/git fixtures for SDK tests

• Provides helpers for creating temp dirs/repos and writing various config shapes (valid, failing, malformed, syntax error, JS fallback) for plan/execute/config tests.

packages/sdk/src/tests/helpers/fixtures.ts

load-workflow.test.tsAdd tests for dynamic config import and validation +103/-0

Add tests for dynamic config import and validation

• Verifies loadWorkflow imports valid configs and throws SdkError with correct codes for invalid exports, syntax errors (cause preserved), and missing files.

packages/sdk/src/tests/load-workflow.test.ts

plan-mode.test.tsAdd plan() behavior tests for config and auto-discovery +53/-0

Add plan() behavior tests for config and auto-discovery

• Ensures plan() returns a proposal when no config exists, returns operations when config is provided, and does not execute commands in plan mode.

packages/sdk/src/tests/plan-mode.test.ts

public-api.test.tsAdd public API and SdkError contract tests +69/-0

Add public API and SdkError contract tests

• Checks SdkError construction and that exported public types are importable/usable for compile-time validation.

packages/sdk/src/tests/public-api.test.ts

re-exports.test.tsAdd re-export surface tests for @sverka/sdk +108/-0

Add re-export surface tests for @sverka/sdk

• Asserts the SDK exports expected functions/classes from core/ir/planner/runtime/findings/policy plus SDK-level helpers and entrypoints.

packages/sdk/src/tests/re-exports.test.ts

task.test.tsAdd tests for task() operation naming helper +25/-0

Add tests for task() operation naming helper

• Ensures task(name, op) returns a correctly named Operation and matches op.named(name) behavior.

packages/sdk/src/tests/task.test.ts

Documentation (2) +589 / -322
wave-09-sdk-plan.mdAdd Wave 09 SDK implementation plan document +312/-0

Add Wave 09 SDK implementation plan document

• Introduces a detailed architecture/TDD plan describing the SDK as the composition root, config discovery/loading, workflow evaluation, plan conversion, execute pipeline, and error handling expectations.

engdocs/architecture/wave-09-sdk-plan.md

spec.mdUpdate Wave 09 spec to match implemented SDK API and behavior +277/-322

Update Wave 09 spec to match implemented SDK API and behavior

• Refines goals/non-goals (drops compile mode for now), documents execute/plan flows, config discovery rules, conversion defaults, result types, and error semantics aligned with the implementation.

specs/09-sdk/spec.md

Other (3) +26 / -6
bun.lockRegister workspace dependencies for @sverka/sdk +10/-0

Register workspace dependencies for @sverka/sdk

• Adds @sverka/sdk workspace dependencies on core/ir/planner/runtime/runtime-host/runtime-docker/findings/policy to the Bun lockfile metadata.

bun.lock

package.jsonFinalize SDK package entrypoints and workspace deps +15/-5

Finalize SDK package entrypoints and workspace deps

• Switches dist outputs to ESM-friendly .mjs and .d.mts and declares workspace dependencies on the Sverka internal packages required by the SDK composition root.

packages/sdk/package.json

project.jsonFix Nx lint command for ESLint 9 flat config +1/-1

Fix Nx lint command for ESLint 9 flat config

• Updates the lint target to run "eslint src" (removing the legacy --ext .ts usage).

packages/sdk/project.json

Comment thread packages/sdk/src/sverka.ts
Comment thread packages/sdk/src/sverka.ts
Comment thread packages/sdk/src/config.ts
Comment thread packages/sdk/src/config.ts
@qodo-code-review

qodo-code-review Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. False conditions still execute 🐞 Bug ≡ Correctness
Description
evaluateWorkflow() forwards core's full ordered operation list, including condition-skipped
operations, into a scheduler that never evaluates condition. Commands wrapped in when(...) can
therefore execute even when their condition is false.
Code

packages/sdk/src/sverka.ts[R223-225]

+  const runtime = new PlanRuntime();
+  const result = await wf.plan(runtime);
+  return result.operations;
Evidence
The SDK returns result.operations; core explicitly skips runtime.evaluate() for false conditions
but then returns the complete ordered list, while the scheduler initializes and schedules every
plan operation without reading condition.

packages/sdk/src/sverka.ts[219-225]
packages/core/src/internal/plan.ts[47-65]
packages/core/src/composables/when.ts[4-15]
packages/runtime/src/scheduler.ts[69-85]
packages/runtime/src/scheduler.ts[115-169]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The SDK sends condition-skipped operations to the scheduler, so `when(...)` does not prevent execution.

## Issue Context
Core's planning result replaces the runtime's recorded operations with the complete ordered graph. Preserve the planning-time skip decision in a form the scheduler honors; ensure dependencies of skipped operations continue with the scheduler's existing `skipped` semantics.

## Fix Focus Areas
- packages/sdk/src/sverka.ts[219-225]
- packages/sdk/src/internal/plan-runtime.ts[14-37]
- packages/runtime/src/scheduler.ts[115-169]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Default HostExecutor env omits PATH ✓ Resolved 🐞 Bug ☼ Reliability
Description
The SDK’s default HostExecutor is created with an empty envAllowlist and no config.env, so
buildEnv() constructs a child environment that omits PATH from process.env. Because Node’s spawn()
uses options.env when provided and Unix PATH lookup falls back only to /usr/bin:/bin when PATH is
missing, user-local commands (e.g., bun, npm-installed binaries, project-local node_modules/.bin
tools) can fail to spawn with ENOENT.
Code

packages/sdk/src/sverka.ts[R256-260]

+  return new HostExecutor({
+    enabled: true,
+    allowlist: allowAllCommands,
+    envAllowlist: [],
+  });
Evidence
In packages/sdk/src/sverka.ts, createExecutor() constructs a HostExecutor with envAllowlist: [], and
in packages/runtime-host/src/host-executor.ts, buildEnv() starts from an empty environment and only
copies host variables whose keys appear in config.envAllowlist, so PATH is dropped by default. This
is corroborated by the project’s own fixtures/tests that explicitly include PATH, and by Node’s
documented spawn() semantics: when an explicit options.env is passed without PATH, Unix command
resolution uses only a minimal fallback (/usr/bin:/bin) rather than the user’s actual PATH, which
would prevent resolving tools referenced by the SDK’s own configuration examples.

packages/sdk/src/sverka.ts[256-260]
packages/runtime-host/src/host-executor.ts[165-189]
packages/runtime-host/src/host-executor.ts[165-188]
packages/runtime-host/src/tests/helpers/fixtures.ts[48-59]
packages/runtime-host/src/tests/host-executor.test.ts[155-164]
packages/sdk/src/index.ts[90-96]
🌐 The command lookup is performed using the options.env.PATH environment variable if env is in the options object. If options.env is set without PATH, lookup on Unix is performed on a default search path of /usr/bin:/bin.

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The SDK’s default `HostExecutor` is constructed with `envAllowlist: []`, so `HostExecutor.buildEnv()` never forwards `PATH` from `process.env` into the environment passed to `child_process.spawn()`. When `spawn()` is invoked with an explicit `options.env` that lacks `PATH`, Unix command resolution falls back only to `/usr/bin:/bin`, causing commands that rely on user/project PATH entries (e.g., `bun`, version-manager-installed tools, npm-installed binaries, `node_modules/.bin`) to fail with `ENOENT`.

## Issue Context
`createExecutor()` in `packages/sdk/src/sverka.ts` builds the default `HostExecutor` config used by `execute()`/`sverka.execute()`. `HostExecutor.buildEnv()` in `packages/runtime-host/src/host-executor.ts` constructs a fresh child environment and only copies keys explicitly listed in `config.envAllowlist`, so an empty allowlist drops all host variables including `PATH`. Environment filtering should remain, but the default host execution path should forward at least the minimum variables required for normal command execution (at least `PATH`), and consider whether platform-specific essentials such as `HOME`, `SystemRoot`, or `PATHEXT` are also needed.

## Fix Focus Areas
- packages/sdk/src/sverka.ts[245-261]
- packages/runtime-host/src/host-executor.ts[165-189]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Docker mode uses invalid flag ✓ Resolved 🐞 Bug ≡ Correctness
Description
The newly selected DockerExecutor constructs docker run --timeout, but docker run has no
--timeout option. Every Docker-mode operation that reaches execution is rejected before its
container starts.
Code

packages/sdk/src/sverka.ts[R250-254]

+  if (type === "docker") {
+    return new DockerExecutor({
+      runAs: "1000:1000",
+      cacheDir,
+    });
Evidence
The SDK activates DockerExecutor; that executor always inserts --timeout in the docker run
arguments. Docker's run reference lists --stop-timeout, not --timeout, and the repository's
real-Docker tests are skipped by default.

packages/sdk/src/sverka.ts[245-254]
packages/runtime-docker/src/docker-executor.ts[42-58]
packages/runtime-docker/src/tests/integration.test.ts[5-7]
🌐 The documented docker run options include --stop-timeout; no --timeout run option is defined.

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
SDK Docker execution activates an executor that passes unsupported `--timeout` arguments to `docker run`.

## Issue Context
The executor already enforces wall-clock timeout by terminating the Docker CLI process. Remove the invalid run argument (or use a supported option only for its documented stop-timeout semantics) and add a real-Docker execution test.

## Fix Focus Areas
- packages/sdk/src/sverka.ts[245-254]
- packages/runtime-docker/src/docker-executor.ts[42-58]
- packages/runtime-docker/src/__tests__/integration.test.ts[5-24]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Temp artifact/cache dirs never cleaned up ✓ Resolved 🐞 Bug ☼ Reliability
Description
doExecute() creates two unique temporary directories (sverka-artifacts-* and sverka-cache-*) via
mkdtempSync on every execute() call, but cleanup only disposes the scheduler/executors and never
removes these directories. As a result, both successful and failed SDK runs leak artifact output and
cache data on disk, accumulating indefinitely across repeated CI/local runs.
Code

packages/sdk/src/sverka.ts[R138-150]

+  const artifactDir = mkdtempSync(join(tmpdir(), "sverka-artifacts-"));
+  const cacheDir = mkdtempSync(join(tmpdir(), "sverka-cache-"));
+  const executor = createExecutor(executorType, root, cacheDir);
+
+  const scheduler = new Scheduler({
+    executors: [executor],
+    maxConcurrent: 4,
+    workspace: root,
+    artifactDir,
+    cacheDir,
+    credentials: {},
+    resume: false,
+  });
Evidence
In packages/sdk/src/sverka.ts, artifactDir and cacheDir are created using mkdtempSync and passed
into the Scheduler, but the surrounding cleanup logic only calls scheduler.dispose() in a finally
block. The Scheduler’s dispose implementation in packages/runtime/src/scheduler.ts only forwards
disposal to Executor.dispose() implementations, and the referenced host/Docker executors do not
delete the provided filesystem paths, while sverka.ts contains no rm/rmSync (or equivalent) calls
for artifactDir or cacheDir, demonstrating that the temporary directories are never removed.

packages/sdk/src/sverka.ts[138-163]
packages/runtime/src/scheduler.ts[480-487]
packages/sdk/src/sverka.ts[137-163]
packages/runtime/src/scheduler.ts[480-491]
packages/runtime-host/src/host-executor.ts[141-143]
packages/runtime-docker/src/docker-executor.ts[234-236]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`doExecute()` allocates two per-execution `mkdtempSync` directories (artifacts and cache) but never deletes them; current cleanup only calls `scheduler.dispose()`, which disposes executors but does not remove the directories, so each SDK `execute()` leaks temp data on disk.

## Issue Context
The SDK creates unique artifact and cache directories for each run and passes them into the scheduler/executors; however, filesystem cleanup for these temp dirs is missing, so both successful and failed runs accumulate temporary command output and cache data indefinitely. Add explicit cleanup in a `finally` block that also covers failures during scheduler/executor construction and execution, and consider/define an artifact retention policy so returned artifact paths remain usable when needed while transient cache data and non-retained artifacts are removed.

## Fix Focus Areas
- packages/sdk/src/sverka.ts[137-163]
- packages/sdk/src/sverka.ts[188-195]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. generatedBy hardcoded to manual 🐞 Bug ≡ Correctness
Description
convertToPlan() always sets metadata.generatedBy to "manual" regardless of whether a user config was
loaded or the plan came from auto-discovery, but the spec requires generatedBy to be "planner" when
no config exists. This mislabels the provenance of plans built without a user config, which is
meaningful data since PlanMetadata.generatedBy explicitly distinguishes "planner" | "manual" |
"compiler".
Code

packages/sdk/src/convert.ts[R40-43]

+  const metadata: PlanMetadata = {
+    sverkaVersion: "0.1.0",
+    generatedBy: "manual",
+  };
Evidence
convert.ts hardcodes generatedBy: "manual" with no parameterization by convert options. The spec
(specs/09-sdk/spec.md) explicitly documents metadata.generatedBy as config ? "manual" : "planner",
and packages/ir/src/plan.ts's PlanMetadata type allows a distinct "planner" value, confirming the
field is meant to distinguish the two cases.

packages/sdk/src/convert.ts[40-43]
packages/ir/src/plan.ts[102-107]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`convertToPlan()` always sets `metadata.generatedBy` to `"manual"`, but the spec requires `"planner"` when the plan was produced without a user config (auto-discovery path). This is a metadata correctness bug that mislabels plan provenance.

## Issue Context
`ConvertOptions` in `packages/sdk/src/convert.ts` has no field indicating whether a user config was resolved; `doExecute()` in `packages/sdk/src/sverka.ts` knows this (via `configPath !== null`) but doesn't pass it through.

## Fix Focus Areas
- packages/sdk/src/convert.ts[20-27]
- packages/sdk/src/convert.ts[40-43]
- packages/sdk/src/sverka.ts[96-124]

Add a `generatedBy` (or `hasConfig`) field to `ConvertOptions`, thread it from `doExecute()` based on whether `configPath` resolved, and use it instead of the hardcoded literal.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. package.json missing @sverka/planner dependency 🐞 Bug ☼ Reliability
Description
packages/sdk/package.json's new dependencies block omits @sverka/planner even though sverka.ts and
types.ts import createPlanner and ProjectContext/PlanProposal from @sverka/planner at runtime;
bun.lock's sdk entry correctly lists @sverka/planner, so the package.json and lockfile are
inconsistent, which risks install/publish failures or accidental undeclared-dependency resolution
outside the monorepo workspace.
Code

packages/sdk/package.json[R21-30]

+  "dependencies": {
+    "@sverka/core": "workspace:*",
+    "@sverka/ir": "workspace:*",
+    "@sverka/planner": "workspace:*",
+    "@sverka/runtime": "workspace:*",
+    "@sverka/runtime-host": "workspace:*",
+    "@sverka/runtime-docker": "workspace:*",
+    "@sverka/findings": "workspace:*",
+    "@sverka/policy": "workspace:*"
+  },
Evidence
The new dependencies object in packages/sdk/package.json lists core, ir, runtime, runtime-host,
runtime-docker, findings, policy, but omits planner, while packages/sdk/src/sverka.ts imports
createPlanner and types from @sverka/planner, and bun.lock's packages/sdk entry (lines 173-182)
does include @sverka/planner: workspace:*. This mismatch means the declared package manifest
under-declares a real runtime dependency.

packages/sdk/package.json[21-30]
packages/sdk/src/sverka.ts[9]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`packages/sdk/package.json`'s dependencies list is missing `@sverka/planner`, even though the SDK imports `createPlanner` and planner types at runtime, and `bun.lock` already reflects `@sverka/planner` as a dependency for the sdk workspace package.

## Issue Context
This inconsistency between the manifest and the lockfile/actual usage can cause resolution issues if the lockfile is regenerated or if the package is published/installed outside the current workspace state.

## Fix Focus Areas
- packages/sdk/package.json[21-30]

Add `"@sverka/planner": "workspace:*"` to the `dependencies` object, matching bun.lock and the actual `@sverka/planner` imports in `src/sverka.ts` and `src/types.ts`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context
✅ Web pages:
  +12 more
Review mode: 🧠 Deep: This is a new SDK composition root with substantial execution, config-loading, plan-conversion, and public API logic across many independent edit sites, making multiple subtle defects plausible.

Grey Divider

Tip of the day
💡 Did you know, you can group findings by type and pick your Finding display, from Minimal to Full

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread packages/sdk/src/sverka.ts
Comment thread packages/sdk/src/sverka.ts
Comment thread packages/sdk/src/sverka.ts
Comment thread packages/sdk/src/convert.ts
Comment thread packages/sdk/src/sverka.ts Outdated
Comment thread packages/sdk/package.json

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 23 files

Tip: instead of fixing issues one by one fix them all with cubic
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

Comment thread engdocs/architecture/wave-09-sdk-plan.md
Comment thread engdocs/architecture/wave-09-sdk-plan.md
Comment thread engdocs/architecture/wave-09-sdk-plan.md
Comment thread packages/sdk/src/__tests__/convert.test.ts
Comment thread packages/sdk/src/sverka.ts
Comment thread packages/sdk/src/types.ts
Comment thread packages/sdk/src/convert.ts
Comment thread packages/sdk/src/__tests__/errors.test.ts
Comment thread packages/sdk/src/config.ts
Comment thread packages/sdk/src/__tests__/find-config.test.ts
@ThePlenkov ThePlenkov mentioned this pull request Aug 10, 2026
9 tasks done
@codeant-ai codeant-ai Bot added size:XXL This PR changes 1000+ lines, ignoring generated files and removed size:XXL This PR changes 1000+ lines, ignoring generated files labels Aug 10, 2026
@sonarqubecloud

Copy link
Copy Markdown

❌ The last analysis has failed.

See analysis details on SonarQube Cloud

@coderabbitai coderabbitai Bot mentioned this pull request Aug 11, 2026
5 tasks done
ThePlenkov and others added 11 commits August 11, 2026 15:38
SDK composition root: re-exports from core, ir, runtime, runtime-host,
runtime-docker, findings, policy. High-level API: createSverka(),
discover(), plan(), execute(), evaluate(). Config file discovery
(sverka.config.ts). 60 tests pass. Reviewer APPROVED with 5
non-blocking nits (untested execute+baseline, EXECUTION_FAILED wrapper,
generatedBy hardcoded, WorkflowDefinition type broadening, validatePlan
skip for empty ops).

<details>
- 60 tests pass (10 files: re-exports, public-api, task, define-workflow, find-config, load-workflow, convert, plan-mode, execute-mode, errors)
- typecheck clean
- build green (dist index.mjs + index.d.mts)
- lint clean
- reviewer approved (sv-3yy)
</details>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Petr Plenkov <petr.plenkov@gmail.com>
…tionalPropertyTypes

Co-Authored-By: Petr Plenkov <petr.plenkov@gmail.com>
Co-Authored-By: Petr Plenkov <petr.plenkov@gmail.com>
- Derive sverkaVersion from package.json at runtime.
- Clamp spec.retries to maxAttempts >= 1.
- Replace cast-based resolveDefaults with explicit field mapping.
- Use canonicalStringify + sorted paths for sourceContextHash.
- Merge duplicate imports; remove unused root param from createExecutor.
- Clean up temp artifact/cache dirs in executePlan finally.
- Pass baseline fingerprints whenever baselinePath is set.
- Simplify mergeOptions by removing unnecessary ?? {} fallbacks.
- Derive Docker runAs from current process uid/gid.
- Improve tests: consolidate execute-mode assertions, meaningful find-config
  bound test, and marker-based plan-mode side-effect assertion.
- Add spec clarity for config lookup, zero-config execute, executor image
  behavior, and canonical source context hash.
- Fix markdown lint in wave-09-sdk-plan.md.

Co-Authored-By: Petr Plenkov <petr.plenkov@gmail.com>
…sourceContextHash changedFiles sort

Co-Authored-By: Petr Plenkov <petr.plenkov@gmail.com>
- Increase cache key hash to 32 hex chars (128 bits) to reduce collision risk.

- Validate configPath is inside project root before dynamic import.

- Wrap executePlan temp dirs cleanup in a top-level try/finally.

- Document trust requirement for the allow-all command allowlist.

Co-Authored-By: Petr Plenkov <petr.plenkov@gmail.com>
Use a dedicated valueOrDefault helper so resolveDefaults no longer contains multiple ?? operators.

Co-Authored-By: Petr Plenkov <petr.plenkov@gmail.com>
Co-Authored-By: Petr Plenkov <petr.plenkov@gmail.com>
Co-Authored-By: Petr Plenkov <petr.plenkov@gmail.com>
@sonarqubecloud

Copy link
Copy Markdown

@ThePlenkov
ThePlenkov merged commit 3e0abc6 into wave-4-runtime-host Aug 11, 2026
4 checks passed
@ThePlenkov
ThePlenkov deleted the wave-9-sdk branch September 23, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

baz: needs review size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant