Skip to content

feat: target-state worker secrets via TaskDef.runtimeMetadata - #311

Merged
v1r3n merged 5 commits into
feature/embedded-secret-togglefrom
feature/embedded-secret-taskdef-target
Jul 10, 2026
Merged

feat: target-state worker secrets via TaskDef.runtimeMetadata#311
v1r3n merged 5 commits into
feature/embedded-secret-togglefrom
feature/embedded-secret-taskdef-target

Conversation

@NicholasDCole

@NicholasDCole NicholasDCole commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Target-state worker-secret delivery for embedded mode, replacing the interim __resolved_credentials__ enrich-stamping shipped in #307. Based on feature/embedded-secret-toggle so the interim stays intact and this can be pointed at / reverted independently.

Mechanism (conductor-oss PR #1255): the worker's TaskDef.runtimeMetadata declares its secret names; the host resolves them at the SIMPLE task's own poll and injects the values onto the wire-only Task.runtimeMetadata — never persisted to task input, no JS injection, resolved at the right task. System-task delivery is unchanged (LLM keys via the host AI integration; HTTP/MCP/planner headers via ${workflow.secrets}).

Changes

Server (conductor-agentspan)

  • AgentService.registerTaskDef(String, List<String>) stamps TaskDef.runtimeMetadata only when EmbeddedMode.isEmbedded() && names non-empty; standalone leaves it empty (native execution-token pull).
  • Removed all interim __resolved_credentials__ stamping (ToolCompiler / JavaScriptBuilder / AgentCompiler / MultiAgentCompiler).
  • Pinned to a local runtimemeta conductor build that carries TaskDef.runtimeMetadata (repin to the published version once PR #1255 releases).
  • WorkerRuntimeMetadataTest — runtimeMetadata declared when embedded, empty standalone, enrich script no longer emits __resolved_credentials__ (fail-first validated).

SDK read-paths (all 4) — swapped __resolved_credentials__task.runtimeMetadata, native token-pull kept as the standalone fallback:

  • Java (readRuntimeMetadata(task), dep → conductor-client:5.1.0), Python (task.runtime_metadata), TypeScript (task.runtimeMetadata, drop the input strip), C# (task.RuntimeMetadata, drop the strip).
  • Read-path unit tests updated/added per SDK (fail-first validated for Java/Python/TS). C# not built locally (no dotnet in the authoring env) — relies on CI.

Coordination

Depends on 4 client-library releases that carry Task.runtimeMetadata (separate PRs to conductor-oss/java-sdk, python-sdk, csharp-sdk, conductor-sdk/conductor-javascript). Dep pins are annotated to repin once those land. Server + SDKs must ship together — a runtimeMetadata-declaring server paired with an SDK reading the old key would starve the worker.

Test evidence

Server + Java/Python/TS SDK unit tests green; each change validated fail-first (broke impl → test failed → restored). Live embedded e2e (persisted task input has no plaintext / no __resolved_credentials__) pending local Orkes run.

🤖 Generated with Claude Code

Test Evidence:

image

NicholasDCole and others added 5 commits July 9, 2026 20:53
…ta (target)

Replace the interim __resolved_credentials__ enrich-script stamping with the
target PR #1255 mechanism: when embedded, the worker's TaskDef declares its
secret names on runtimeMetadata; the host resolves them at the SIMPLE task's
own poll and injects values onto the wire-only Task.runtimeMetadata (never
persisted, no JS injection, resolved at the right task).

- AgentService.registerTaskDef(String, List<String>) stamps runtimeMetadata
  only when EmbeddedMode.isEmbedded() && names non-empty; standalone leaves it
  empty (native execution-token pull still delivers).
- Worker-tool branch passes AgentCompiler.collectToolCredentials(config) names.
- Remove interim stamping: ToolCompiler workerCred helpers + enrich args,
  JavaScriptBuilder workerCredJson params/vars/injection, setWorkerCreds calls
  in AgentCompiler/MultiAgentCompiler.
- Pin conductorVersion to the local runtimemeta build (has TaskDef.runtimeMetadata).
- Replace ToolCompilerWorkerCredTest with WorkerRuntimeMetadataTest: asserts
  runtimeMetadata declared when embedded, empty standalone, and the enrich
  script no longer emits __resolved_credentials__ (validated fail-first).

System-task delivery unchanged (LLM keys via host AI integration; HTTP/MCP/
planner headers via ${workflow.secrets}).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…a (target)

Switch all four SDK worker read-paths from the interim __resolved_credentials__
task-input key to the target Task.runtimeMetadata wire field (conductor-oss PR
#1255): the host resolves the worker's declared TaskDef.runtimeMetadata secret
names at the SIMPLE task's own poll and injects the values on the wire only —
never persisted to task input. The native execution-token pull stays as the
standalone fallback.

- Java: WorkerManager.readRuntimeMetadata(task) reads task.getRuntimeMetadata();
  dep bump conductor-client 5.0.1 -> 5.1.0 (+ mavenLocal for the local build);
  ReadResolvedCredentialsTest -> ReadRuntimeMetadataTest (fail-first validated).
- Python: _dispatch reads task.runtime_metadata; test_resolved_credentials ->
  test_runtime_metadata (fail-first validated).
- TypeScript: worker.ts reads task.runtimeMetadata (structural cast so it compiles
  against the current client until the OpenAPI type releases); drop the
  __resolved_credentials__ strip; new worker.test.ts host-delivered case
  (fail-first validated). credentials.test.ts accessor path already aligned.
- C#: WorkerManager.ReadRuntimeMetadata(task) reads task.RuntimeMetadata; drop the
  input strip; RuntimeMetadataReadTests via reflection. Not built here (no dotnet).

Client deps require releases carrying Task.runtimeMetadata; pins annotated to
repin once those land. Ships together with the server switchover so a
runtimeMetadata-declaring server is never paired with an SDK reading the old key.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…adata isn't clobbered

The SDK self-registered each worker TaskDef with overwrite semantics, using a bare def. When
embedded, the host server pre-registers the worker TaskDef and declares its secret names on
TaskDef.runtimeMetadata (conductor-oss PR #1255) — overwriting with a bare def (the client TaskDef
model carries no runtimeMetadata field) clobbered that and starved the host resolver, so
Task.runtimeMetadata arrived empty and secrets never resolved.

Fix, flag-free (no embedded prop): register create-only — create the TaskDef when absent, never
overwrite one that exists. Embedded, the server's def (with runtimeMetadata) is left intact;
standalone still gets the def created when missing. The existence check chooses correctly with no
configuration, so it "just works" either way.

- Python: ToolRegistry.register_tool_workers + the framework worker path use overwrite_task_def=False
  (conductor-python then does get_task_def → skip-if-exists → else register).
- Java: WorkerManager.registerTaskDef checks metadataClient.getTaskDef first and skips when present.
- Tests (fail-first validated): Python test_embedded_taskdef_registration asserts create-only;
  Java EmbeddedTaskDefRegistrationTest asserts no-overwrite-when-exists / create-when-absent.

Surfaced by the local embedded webhook e2e. TS/C# SDKs don't self-register worker TaskDefs, so they
were already correct.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@v1r3n
v1r3n merged commit 3aa2b9e into feature/embedded-secret-toggle Jul 10, 2026
@v1r3n
v1r3n deleted the feature/embedded-secret-taskdef-target branch July 10, 2026 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants