From 38e4ec6f69d23c663f60c44c311217f7239e448d Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 11:53:37 -0400 Subject: [PATCH 01/14] Add scoped Claude SDK OmniRoute worker trial --- examples/claude-runtime-sdk/README.md | 160 +++++ .../tests/check_controls.py | 31 + .../claude-runtime-sdk/tests/test_worker.py | 446 +++++++++++++ examples/claude-runtime-sdk/verification.md | 95 +++ examples/claude-runtime-sdk/worker.py | 497 ++++++++++++++ examples/claude-runtime-sdk/worker.py.lock | 610 ++++++++++++++++++ 6 files changed, 1839 insertions(+) create mode 100644 examples/claude-runtime-sdk/README.md create mode 100644 examples/claude-runtime-sdk/tests/check_controls.py create mode 100644 examples/claude-runtime-sdk/tests/test_worker.py create mode 100644 examples/claude-runtime-sdk/verification.md create mode 100644 examples/claude-runtime-sdk/worker.py create mode 100644 examples/claude-runtime-sdk/worker.py.lock diff --git a/examples/claude-runtime-sdk/README.md b/examples/claude-runtime-sdk/README.md new file mode 100644 index 000000000..f2d5e719c --- /dev/null +++ b/examples/claude-runtime-sdk/README.md @@ -0,0 +1,160 @@ +# Claude SDK workers through OmniRoute + +This is a thin integration of the official Claude Agent SDK, pinned to +[`anthropics/claude-agent-sdk-python` v0.2.162](https://github.com/anthropics/claude-agent-sdk-python/tree/f2204bb956bab02907aaf3cb88eb9dead28eaa35) +(`f2204bb956bab02907aaf3cb88eb9dead28eaa35`). The +[release](https://github.com/anthropics/claude-agent-sdk-python/releases/tag/v0.2.162) +bundles Claude Code 2.1.285. The SDK owns the agent loop, tool execution, +native context/cache/compaction and sessions. Our script supplies worker-scoped +transport, a bounded lifecycle and value-free observations. + +The default candidate `dva/claude-opus-5-max` is an advertised OmniRoute Claude +route, pending live qualification. Its name does not attest the serving provider +or model, and advertised Opus 5 is different from the native coordinator's +Opus 5.5. This integration does not select a framework winner or certify every +installed skill, hook, plugin, MCP server or background workflow. The coordinator +retains its native session and authentication. + +## Installation and configuration + +Use the installed uv 0.12.17 and the committed PEP 723 script lock. These are the +[supported uv script commands](https://docs.astral.sh/uv/guides/scripts/#locking-dependencies); +the package installation is the SDK's +[official PyPI installation](https://github.com/anthropics/claude-agent-sdk-python/blob/f2204bb956bab02907aaf3cb88eb9dead28eaa35/README.md#installation). + +```sh +rtk uv lock --script examples/claude-runtime-sdk/worker.py --check +rtk uv run --frozen --script examples/claude-runtime-sdk/worker.py --preflight +``` + +Preflight makes no provider request. It reports selected options, package pin, +loopback port and capability configuration without printing paths, settings or +credentials. `CLAUDE_CODE_EFFORT_LEVEL` must be absent from the launcher process: +the native variable can override the explicit `effort="max"`. Remove it only from +the worker launch environment when needed; do not change the coordinator's +environment or settings. The standalone worker adopts OmniRoute's pinned +[`buildClaudeEnv`](https://github.com/diegosouzapw/OmniRoute/blob/2f42a9ac19d1a247ec9ce5473b790843724b3061/bin/cli/commands/launch.mjs#L23) +transport: it removes inherited `ANTHROPIC_*` from its own process, sets the +loopback Anthropic root (normally `http://127.0.0.1:20128`, without `/v1`), enables +native gateway model discovery and supplies the documented `omniroute-no-auth` +sentinel for a keyless loopback gateway. An authenticated gateway may use +`--gateway-token-env APPLICATION_BINDING`: the runtime copies that opaque +application-specific value into the native child option without printing it. +Missing bindings and attempted native `ANTHROPIC_*` credential reuse fail closed. +The SDK merges child options onto its process environment, so the filtering +occurs in the standalone worker before connection; importing `run_worker` into +an unrelated application is not a qualified isolation boundary. + +The native coordinator environment is unaffected. The launcher source's fixed +190,000-token compaction window is excluded; native context policy is retained. +Use the selected host's native credential recipe. This script does not read +authentication stores, select accounts, restart OmniRoute or configure a remote +service. A sentinel is transport setup, not gateway/provider readiness evidence. + +The modern-python skill's statement that PEP 723 scripts have no lockfile was +checked against installed `uv lock --help`: uv 0.12.17 supports `--script`, and +the official script guide documents `worker.py.lock`. The native command is the +source of truth for this correction. + +## Full native capabilities with conditional skills + +[`ClaudeAgentOptions`](https://github.com/anthropics/claude-agent-sdk-python/blob/f2204bb956bab02907aaf3cb88eb9dead28eaa35/src/claude_agent_sdk/types.py) +uses the `claude_code` system prompt preset, an explicit Claude-family model, +`effort="max"`, a selected cwd and `setting_sources=["user", "project"]` by +default. The `tools` option stays unset, retaining the full native toolset. +`--allow-tool` changes permission auto-approval, not tool availability; +`dontAsk` retains native deny rules and denies requests that lack permission. +No bypass mode is introduced. + +Installed skill metadata is discovered through those native sources. `--skill +all` exposes every discovered skill, and repeated `--skill NAME` enables an exact +task-matched selection; the SDK loads bodies when the model invokes a skill. +Read a selected `SKILL.md` before acting. Use the repository's +[skill lifecycle](../../adoption/skills/lifecycle.md) to install, update, activate +or recover skills. This runner does not duplicate the skill catalog or preload +all bodies. Native subagent `skills:` fields preload bodies and remain a separate +role definition: do not copy the whole main-session selection into each child. +See the [official SDK skill guide](https://platform.claude.com/docs/en/agent-sdk/skills) +and pinned [`_apply_skills_defaults`](https://github.com/anthropics/claude-agent-sdk-python/blob/f2204bb956bab02907aaf3cb88eb9dead28eaa35/src/claude_agent_sdk/_internal/transport/subprocess_cli.py). + +Choose sources deliberately. For a clean acceptance fixture, `--setting-source +project` excludes user settings while keeping project configuration. Select local +plugins explicitly with `--plugin PATH`; the SDK's supported local plugin format +can supply skills, agents, hooks and MCP servers. `--mcp-config PATH` adds a native +MCP configuration, and the selected settings retain their native hooks and +subagent definitions. The script does not read or reserialize those settings, +inject a fixed context window, disable compaction, or replace native discovery. +Actual hook/MCP/plugin activation needs an observed worker run. + +## Run, interrupt and recover + +Supply a prompt on stdin and an isolated owned cwd. A run contains one native +SDK query and no retries. The native client handles additional model/tool turns. +The runner observes the first native result, so independent background jobs need +their own completion and usage qualification. + +```sh +rtk uv run --frozen --script examples/claude-runtime-sdk/worker.py \ + --cwd "$WORKER_CHECKOUT" --setting-source project \ + --skill search-first --allow-tool Read --timeout 180 \ + --result-output "$PRIVATE_RUN/returned.txt" < "$PRIVATE_RUN/prompt.txt" +``` + +`--interrupt-after SECONDS` sends one supported `ClaudeSDKClient.interrupt()` +request. A timeout sends that native interrupt, drains for up to four seconds, +then uses the SDK's shielded subprocess cleanup. Connection has the same overall +deadline; native cleanup has its own termination/kill grace. This does not prove +remote-provider cancellation or reverse external effects. A later run may use +`--resume SESSION_UUID` with the same cwd and native session storage. Inspect +completed effects before resuming; there is no automatic resubmission. +`--fork-session` uses the native fork option when explicitly requested. + +Stdout contains a sanitized summary: native session ID, init capability +names/counts, tool-call names/IDs/counts, selected Skill name, tool-result +IDs/error flags, result length/hash, last-result state and numeric usage. +Returned text is optional, written only to a new 0600 file specified by +`--result-output`; keep that file and raw logs outside the checkout. SDK exception +text, prompts, tool inputs/outputs, settings, paths and credential values are +omitted. Publish only a separately reviewed compact receipt. + +Native `model_usage` is retained as the latest session snapshot; snapshots are +never added. `usage` from the last result stays separate. Cache read/write +categories are not added to input tokens, native cost is not a billing claim, +and missing counters/cost remain unknown. Executor/advisor/provider complete +usage requires independent reconciliation; these SDK fields do not imply that +an advisor run was captured. + +The current Devin bridge's +[`estimateTokens`](https://github.com/diegosouzapw/OmniRoute/blob/2f42a9ac19d1a247ec9ce5473b790843724b3061/open-sse/executors/devin-agentic/types.ts#L54) +uses a text-length estimate. Its +[`serializer`](https://github.com/diegosouzapw/OmniRoute/blob/2f42a9ac19d1a247ec9ce5473b790843724b3061/open-sse/executors/devin-agentic/serializer.ts) +also caps individual tool results at 65,536 characters and marks truncation. +These route behaviors require a workload-specific information-contract check; +SDK-emitted counters do not prove provider measurements or native cache reuse. +An empty/zero native snapshot after a failed request is not proof of zero spend. + +## Validation scope + +The local tests are synthetic configuration/lifecycle/accounting checks against +the pinned SDK types and transport. They contain discriminating wrong-route, +wrong-family, token-binding, missing-result, cancellation and cumulative-snapshot cases. They +are not unchanged upstream tests or live provider evidence. + +```sh +rtk uv run --frozen --script examples/claude-runtime-sdk/worker.py --preflight +rtk uv run --with claude-agent-sdk==0.2.162 \ + python -m unittest discover -s examples/claude-runtime-sdk/tests -v +rtk uv run --with claude-agent-sdk==0.2.162 \ + python examples/claude-runtime-sdk/tests/check_controls.py --disarm-route +# The disarmed route check must fail (exit 1). +rtk uv run --with claude-agent-sdk==0.2.162 \ + python examples/claude-runtime-sdk/tests/check_controls.py +# The same armed oracle must pass (exit 0). +``` + +Unchanged upstream tests are run from the exact pinned official checkout using +its documented developer installation and `.github/workflows/test.yml` command. +They are recorded separately from the local fixtures and from the coordinator's +bounded OmniRoute live acceptance. A valid model response alone does not qualify +tools, task-selected skills, MCP/plugin/hooks, recovery, usage completeness or +the matched three-arm SDK selection gate. diff --git a/examples/claude-runtime-sdk/tests/check_controls.py b/examples/claude-runtime-sdk/tests/check_controls.py new file mode 100644 index 000000000..728fdb4a4 --- /dev/null +++ b/examples/claude-runtime-sdk/tests/check_controls.py @@ -0,0 +1,31 @@ +"""Run the same local oracle with a route guard deliberately disarmed. + +This is synthetic fault injection using unittest.mock, as in the pinned SDK's +tests/test_transport.py. A disarmed check must return 1, then the armed check 0. +""" + +import argparse +import unittest +from unittest.mock import patch + +import test_worker + + +def main(): + args = argparse.ArgumentParser(description=__doc__) + args.add_argument("--disarm-route", action="store_true") + parsed = args.parse_args() + suite = unittest.defaultTestLoader.loadTestsFromName( + "ConfigurationTests.test_wrong_route_is_rejected_before_a_client_exists", + test_worker, + ) + if parsed.disarm_route: + with patch.object(test_worker.worker, "loopback_root", lambda value: value): + result = unittest.TextTestRunner(verbosity=2).run(suite) + else: + result = unittest.TextTestRunner(verbosity=2).run(suite) + return 0 if result.wasSuccessful() else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/examples/claude-runtime-sdk/tests/test_worker.py b/examples/claude-runtime-sdk/tests/test_worker.py new file mode 100644 index 000000000..01ba0c9fb --- /dev/null +++ b/examples/claude-runtime-sdk/tests/test_worker.py @@ -0,0 +1,446 @@ +"""Synthetic integration controls; no provider calls or native session claims.""" + +from __future__ import annotations + +import importlib.util +import os +import sys +import tempfile +import unittest +import uuid +from pathlib import Path +from unittest.mock import patch + +import anyio +from claude_agent_sdk import ( + AssistantMessage, + ResultMessage, + SystemMessage, + ToolUseBlock, +) +from claude_agent_sdk._internal.transport.subprocess_cli import SubprocessCLITransport + +SCRIPT = Path(__file__).resolve().parents[1] / "worker.py" +SPEC = importlib.util.spec_from_file_location("claude_runtime_worker", SCRIPT) +worker = importlib.util.module_from_spec(SPEC) +sys.modules[SPEC.name] = worker +SPEC.loader.exec_module(worker) +# Construct a reproducible fixture identity; never publish a native session ID. +SESSION = str(uuid.uuid5(uuid.NAMESPACE_DNS, "claude-runtime-sdk.synthetic-session")) + + +def result(**kwargs): + fields = dict( + subtype="success", + duration_ms=10, + duration_api_ms=5, + is_error=False, + num_turns=1, + session_id=SESSION, + terminal_reason="completed", + result="fixture result", + ) + fields.update(kwargs) + return ResultMessage(**fields) + + +class ConfigurationTests(unittest.TestCase): + def setUp(self): + self.temp = tempfile.TemporaryDirectory() + self.addCleanup(self.temp.cleanup) + self.cwd = Path(self.temp.name) + self.environment = patch.dict(os.environ, {}, clear=True) + self.environment.start() + self.addCleanup(self.environment.stop) + + def options(self, *args): + return worker.build_options( + worker.parser().parse_args(["--cwd", str(self.cwd), *args]) + ) + + def command(self, options): + # Build SDK argv only. This synthetic executable is never launched. + options.cli_path = sys.executable + return SubprocessCLITransport( + prompt="fixture", options=options + )._build_command() + + def test_native_transport_has_full_preset_and_scoped_route(self): + options = self.options() + command = self.command(options) + self.assertEqual(command[command.index("--model") + 1], worker.DEFAULT_MODEL) + self.assertEqual(command[command.index("--effort") + 1], "max") + self.assertNotIn("--tools", command) + self.assertEqual( + options.system_prompt, {"type": "preset", "preset": "claude_code"} + ) + self.assertEqual(options.env["ANTHROPIC_BASE_URL"], worker.DEFAULT_GATEWAY) + self.assertEqual(options.env["ANTHROPIC_AUTH_TOKEN"], "omniroute-no-auth") + self.assertEqual(options.env["CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"], "1") + self.assertNotIn("ANTHROPIC_API_KEY", options.env) + self.assertIsNone(options.fallback_model) + self.assertNotIn("190000", str(options)) + + def test_exact_skills_use_native_permissions_without_body_preload(self): + options = self.options( + "--skill", "search-first", "--skill", "context-mode:context-mode" + ) + command = self.command(options) + grants = command[command.index("--allowedTools") + 1] + self.assertIn("Skill(search-first)", grants) + self.assertIn("Skill(context-mode:context-mode)", grants) + self.assertNotIn("--tools", command) + self.assertEqual(options.allowed_tools, []) + self.assertIsNone(options.agents) + self.assertIn("--setting-sources=user,project", command) + self.assertNotIn("SKILL.md", " ".join(command)) + + def test_all_skills_keeps_native_discovery(self): + options = self.options("--skill", "all") + command = self.command(options) + self.assertEqual(command[command.index("--allowedTools") + 1], "Skill") + self.assertEqual(options.skills, "all") + self.assertEqual(options.allowed_tools, []) + + def test_project_only_selected_plugin_and_mcp_path(self): + plugin = self.cwd / "plugin" + plugin.mkdir() + mcp = self.cwd / "mcp.json" + mcp.write_text('{"mcpServers":{}}') + options = self.options( + "--setting-source", + "project", + "--plugin", + str(plugin), + "--mcp-config", + str(mcp), + "--allow-tool", + "Read", + ) + read_text = Path.read_text + + def observe_read(path, *args, **kwargs): + if path == mcp: + raise AssertionError("no caller settings reads") + return read_text(path, *args, **kwargs) + + with patch.object(Path, "read_text", observe_read): + summary = worker.preflight(options) + command = self.command(options) + self.assertIn("--setting-sources=project", command) + self.assertIn("--plugin-dir", command) + self.assertIn("--mcp-config", command) + self.assertTrue(summary["tools_unrestricted"]) + self.assertEqual(summary["plugin_count"], 1) + self.assertNotIn(str(self.cwd), str(summary)) + + def test_wrong_family_is_rejected_without_substitution(self): + for model in ("gpt-6.1-sol", "openai/gpt-6.1-sol", "opus", "gpt-claude-opus-5"): + with ( + self.subTest(model=model), + self.assertRaisesRegex(ValueError, "Claude-family"), + ): + self.options("--model", model) + + def test_wrong_route_is_rejected_before_a_client_exists(self): + for gateway in ( + "https://api.anthropic.com", + "http://127.0.0.1:20128/v1", + "http://user:fixture-secret@127.0.0.1:20128", + "http://127.0.0.1:20128?token=fixture-secret", + "http://127.0.0.1:99999", + ): + with self.subTest(gateway=gateway), self.assertRaises(ValueError): + self.options("--gateway", gateway) + + def test_inherited_effort_fails_closed_and_is_not_printed(self): + os.environ["CLAUDE_CODE_EFFORT_LEVEL"] = "fixture-private-value" + with self.assertRaises(ValueError) as raised: + self.options() + self.assertNotIn("fixture-private-value", str(raised.exception)) + self.assertEqual( + os.environ["CLAUDE_CODE_EFFORT_LEVEL"], "fixture-private-value" + ) + + def test_parent_environment_and_credentials_stay_opaque(self): + os.environ.update( + { + "ANTHROPIC_BASE_URL": "https://fixture-native.invalid", + "ANTHROPIC_AUTH_TOKEN": "opaque-fixture", + } + ) + before = dict(os.environ) + self.options() + self.assertEqual(dict(os.environ), before) + + def test_native_anthropic_keys_are_removed_from_worker_scope(self): + os.environ.update( + { + "ANTHROPIC_API_KEY": "opaque-native-fixture", + "ANTHROPIC_AUTH_TOKEN": "opaque-native-fixture", + "ANTHROPIC_DEFAULT_OPUS_MODEL": "fixture-native-model", + "UNRELATED_FIXTURE": "retained", + } + ) + options = self.options() + self.assertEqual(worker.prepare_worker_environment(), 3) + self.assertFalse(any(name.startswith("ANTHROPIC_") for name in os.environ)) + self.assertEqual(os.environ["UNRELATED_FIXTURE"], "retained") + self.assertEqual(options.env["ANTHROPIC_AUTH_TOKEN"], "omniroute-no-auth") + + def test_gateway_specific_binding_remains_opaque(self): + os.environ["OMNIROUTE_FIXTURE_TOKEN"] = "opaque-gateway-fixture" + options = self.options("--gateway-token-env", "OMNIROUTE_FIXTURE_TOKEN") + summary = worker.preflight(options) + self.assertEqual(options.env["ANTHROPIC_AUTH_TOKEN"], "opaque-gateway-fixture") + self.assertNotIn("opaque-gateway-fixture", str(summary)) + + def test_missing_or_native_token_binding_fails_closed(self): + for binding in ( + "OMNIROUTE_ABSENT_FIXTURE", + "ANTHROPIC_AUTH_TOKEN", + "invalid fixture", + ): + with self.subTest(binding=binding), self.assertRaises(ValueError): + self.options("--gateway-token-env", binding) + + def test_resume_passes_native_identity_and_no_new_fork_by_default(self): + options = self.options("--resume", SESSION) + command = self.command(options) + self.assertIn("--resume=" + SESSION, command) + self.assertNotIn("--fork-session", command) + with self.assertRaisesRegex(ValueError, "UUID"): + self.options("--resume", "/private/transcript.jsonl") + + def test_nonexistent_cwd_plugin_and_mixed_skill_selection_fail(self): + for args in ( + ["--plugin", str(self.cwd / "absent")], + ["--skill", "all", "--skill", "search-first"], + ["--cwd", str(self.cwd / "absent")], + ): + with self.subTest(args=args), self.assertRaises(ValueError): + self.options(*args) + + +class AccountingTests(unittest.TestCase): + def test_cumulative_snapshots_replace_without_cache_double_count(self): + observation = worker.Observation() + first = result( + usage={"input_tokens": 3, "cache_read_input_tokens": 9}, + model_usage={ + "claude-fixture": {"inputTokens": 100, "cacheReadInputTokens": 60} + }, + total_cost_usd=0.1, + ) + last = result( + usage={"input_tokens": 4, "cache_read_input_tokens": 12}, + model_usage={ + "claude-fixture": {"inputTokens": 180, "cacheReadInputTokens": 90} + }, + total_cost_usd=0.2, + ) + observation.observe(first) + observation.observe(last) + summary = observation.summary() + self.assertEqual( + summary["model_usage_latest_session_snapshot"]["claude-fixture"][ + "inputTokens" + ], + 180, + ) + self.assertNotEqual( + summary["model_usage_latest_session_snapshot"]["claude-fixture"][ + "inputTokens" + ], + 280, + ) + self.assertEqual(summary["usage_last_native_result"]["input_tokens"], 4) + self.assertEqual( + summary["usage_last_native_result"]["cache_read_input_tokens"], 12 + ) + self.assertFalse(summary["cache_counters_added_to_input"]) + self.assertEqual(summary["native_reported_cost_usd"], 0.2) + self.assertIsNone(summary["billing_cost_usd"]) + + def test_unknown_counters_replace_prior_known_values_with_unknown(self): + observation = worker.Observation() + observation.observe( + result( + usage={"input_tokens": 1}, + model_usage={"claude-fixture": {"inputTokens": 1}}, + total_cost_usd=0.01, + ) + ) + observation.observe(result()) + summary = observation.summary() + self.assertIsNone(summary["usage_last_native_result"]) + self.assertIsNone(summary["model_usage_latest_session_snapshot"]) + self.assertIsNone(summary["native_reported_cost_usd"]) + + def test_result_and_arbitrary_usage_fields_are_omitted(self): + observation = worker.Observation() + observation.observe( + result( + result="fixture-private-result", + usage={"arbitrary": "fixture-private-value", "input_tokens": 5}, + ) + ) + summary = observation.summary() + self.assertNotIn("fixture-private", str(summary)) + self.assertEqual(summary["result_bytes"], len("fixture-private-result")) + self.assertEqual(summary["usage_last_native_result"], {"input_tokens": 5}) + + def test_skill_event_preserves_identity_without_args_or_body(self): + observation = worker.Observation() + observation.observe( + AssistantMessage( + content=[ + ToolUseBlock( + id="fixture-call", + name="Skill", + input={"skill": "bridge-proof", "args": "fixture-private-text"}, + ) + ], + model="claude-fixture", + ) + ) + summary = observation.summary() + self.assertEqual( + summary["tool_events"], + [{"id": "fixture-call", "name": "Skill", "skill": "bridge-proof"}], + ) + self.assertNotIn("fixture-private-text", str(summary)) + + def test_snapshot_is_detached_from_summary_mutation(self): + observation = worker.Observation() + observation.observe( + result(model_usage={"claude-fixture": {"inputTokens": 180}}) + ) + summary = observation.summary() + summary["model_usage_latest_session_snapshot"]["claude-fixture"][ + "inputTokens" + ] = 999 + self.assertEqual(observation.model_usage["claude-fixture"]["inputTokens"], 180) + + +class SyntheticClient: + """Native-client-shaped control fixture; not an SDK or provider run.""" + + def __init__(self, *, wait=False, missing=False, error=False, terminal="completed"): + self.wait, self.missing, self.error = wait, missing, error + self.interrupted = False + self.events = [] + self.terminal = terminal + self.signal = anyio.Event() + + async def __aenter__(self): + self.events.append("connect") + return self + + async def __aexit__(self, *exc): + self.events.append("disconnect") + + async def query(self, prompt): + self.events.append("query") + if self.error: + raise RuntimeError("fixture-secret /private/path") + + async def interrupt(self): + self.events.append("interrupt") + self.interrupted = True + self.signal.set() + + async def receive_response(self): + if self.wait and not self.interrupted: + await self.signal.wait() + yield SystemMessage( + subtype="init", + data={ + "session_id": SESSION, + "tools": ["Read", "Skill"], + "skills": ["fixture"], + }, + ) + if not self.missing: + yield AssistantMessage( + content=[ + ToolUseBlock(id="fixture", name="Read", input={"secret": "omitted"}) + ], + model="claude-fixture", + ) + yield result( + terminal_reason="aborted_streaming" + if self.interrupted + else self.terminal + ) + + +class LifecycleTests(unittest.TestCase): + def run_case(self, **kwargs): + async def case(): + client = SyntheticClient(**kwargs) + observation = await worker.run_worker( + worker.ClaudeAgentOptions(), + "fixture", + timeout=0.1, + client_factory=lambda **_: client, + ) + return observation, client + + return anyio.run(case) + + def test_one_query_and_native_result_closes_the_client(self): + observation, client = self.run_case() + self.assertEqual(observation.status, "completed") + self.assertEqual(client.events, ["connect", "query", "disconnect"]) + self.assertEqual(observation.tool_calls, {"Read": 1}) + self.assertEqual(observation.init["skills_count"], 1) + + def test_missing_native_result_is_a_failed_condition(self): + observation, client = self.run_case(missing=True) + self.assertEqual(observation.status, "missing_native_result") + self.assertNotEqual(observation.status, "completed") + self.assertEqual(client.events[-1], "disconnect") + + def test_native_turn_limit_is_not_reported_as_completion(self): + observation, client = self.run_case(terminal="max_turns") + self.assertEqual(observation.status, "native_incomplete") + self.assertEqual(observation.last_result["terminal_reason"], "max_turns") + self.assertEqual(client.events[-1], "disconnect") + + def test_timeout_interrupts_then_cleans_up_without_retry(self): + observation, client = self.run_case(wait=True) + self.assertEqual(observation.status, "timeout") + self.assertTrue(observation.interrupt_sent) + self.assertEqual(client.events, ["connect", "query", "interrupt", "disconnect"]) + recovered, recovered_client = self.run_case() + self.assertEqual(recovered.status, "completed") + self.assertEqual(recovered_client.events.count("query"), 1) + + def test_explicit_native_interrupt_is_observed(self): + async def case(): + client = SyntheticClient(wait=True) + observation = await worker.run_worker( + worker.ClaudeAgentOptions(), + "fixture", + timeout=0.2, + interrupt_after=0.01, + client_factory=lambda **_: client, + ) + return observation, client + + observation, client = anyio.run(case) + self.assertEqual(observation.status, "interrupted") + self.assertTrue(observation.interrupt_sent) + self.assertEqual(client.events, ["connect", "query", "interrupt", "disconnect"]) + + def test_exception_text_is_omitted_and_client_cleanup_runs(self): + observation, client = self.run_case(error=True) + self.assertEqual(observation.status, "sdk_error") + self.assertNotIn("fixture-secret", str(observation.summary())) + self.assertNotIn("/private/path", str(observation.summary())) + self.assertEqual(client.events[-1], "disconnect") + + +if __name__ == "__main__": + unittest.main() diff --git a/examples/claude-runtime-sdk/verification.md b/examples/claude-runtime-sdk/verification.md new file mode 100644 index 000000000..7f5f57755 --- /dev/null +++ b/examples/claude-runtime-sdk/verification.md @@ -0,0 +1,95 @@ +# Claude SDK integration verification, 2026-09-30 + +This record covers the source-derived runner and local checks. Live gateway +requests, provider identity, skill/tool activation, native session recovery and +framework selection require the coordinator's separate acceptance receipt. +No model run was performed by this implementation worker. + +## Primary sources and installed observations + +| Source | Pin and observation | Applied boundary | +| --- | --- | --- | +| [Claude Agent SDK Python](https://github.com/anthropics/claude-agent-sdk-python/tree/f2204bb956bab02907aaf3cb88eb9dead28eaa35) | `v0.2.162`, commit `f2204bb956bab02907aaf3cb88eb9dead28eaa35`; annotated tag `bd22c3a79ebee022589212c62f09bc061e225523` dereferenced through `gh api` | Official client, options, transport, skill selection and session/interrupt API | +| [SDK release](https://github.com/anthropics/claude-agent-sdk-python/releases/tag/v0.2.162) | Published 2026-09-29; bundles Claude CLI 2.1.285; installed coordinator `claude --version` also returned 2.1.285 | A version match, not a provider/tool/skill acceptance result | +| [Native SDK source](https://github.com/anthropics/claude-agent-sdk-python/blob/f2204bb956bab02907aaf3cb88eb9dead28eaa35/src/claude_agent_sdk/client.py) | `ClaudeSDKClient.query`, `receive_response`, `interrupt` and context-manager cleanup | One SDK query; no custom model loop, retry or implicit resubmission | +| [Native skill transport](https://github.com/anthropics/claude-agent-sdk-python/blob/f2204bb956bab02907aaf3cb88eb9dead28eaa35/src/claude_agent_sdk/_internal/transport/subprocess_cli.py) | `_apply_skills_defaults`, `_build_command` and shielded cleanup | `skills="all"` or exact names; native setting sources, permission grants and local plugins | +| [OmniRoute launcher](https://github.com/diegosouzapw/OmniRoute/blob/2f42a9ac19d1a247ec9ce5473b790843724b3061/bin/cli/commands/launch.mjs#L23) | `2f42a9ac19d1a247ec9ce5473b790843724b3061`, `buildClaudeEnv`; original tracked blob also inspected in the published source checkout | Worker-process `ANTHROPIC_*` filtering, loopback root, documented keyless sentinel and gateway model discovery; fixed compaction-window override excluded | +| [Devin bridge usage and serialization](https://github.com/diegosouzapw/OmniRoute/tree/2f42a9ac19d1a247ec9ce5473b790843724b3061/open-sse/executors/devin-agentic) | Same OmniRoute pin, `types.ts::estimateTokens` and `serializer.ts::boundedToolResult` | Text-length estimates and a marked 65,536-character tool-result cap; no measured-cache or complete-provider-usage claim | +| [uv scripts](https://docs.astral.sh/uv/guides/scripts/#locking-dependencies) | Installed uv 0.12.17; `uv lock --help` reports `--script`; native lock resolved 32 packages | PEP 723 installation and `worker.py.lock`; no shared environment synchronization | + +The main-model route is an advertised candidate, not an accepted replacement +for the native coordinator model. The runner rejects a non-Claude-family ID and +does not silently substitute one. Native capability configuration is distinct +from activation evidence. + +## Returned checks + +Raw commands and returned logs are retained in the coordinator's private owned +run prefix. Public records omit personal paths, tool inputs/outputs, prompts and +credential values. Local synthetic strings are fixtures, not copied secrets. + +| Check | Evidence class | Returned result | +| --- | --- | --- | +| `uv lock --script examples/claude-runtime-sdk/worker.py --default-index https://pypi.org/simple --no-sources` | Native installation artifact | Exit 0; 32 packages resolved | +| `uv run --frozen --script examples/claude-runtime-sdk/worker.py --preflight` | Configuration only | Exit 0; pinned SDK, effort max, Claude preset/full toolset, loopback root, selected sources and skill metadata policy; no model request | +| Same preflight with `--model gpt-6.1-sol` | Discriminating configuration control | Exit 2; non-Claude family rejected, no substitution | +| `python -m unittest discover -s examples/claude-runtime-sdk/tests -v` through pinned SDK `uv run --with` | Local synthetic integration | Initial two runs: 19 tests, one failure and one error, exit 1; corrected run: 21 tests, exit 0; transport-auth extension: 24 tests, exit 0 in 0.151 seconds | +| `python examples/claude-runtime-sdk/tests/check_controls.py --disarm-route` | Synthetic fault injection | Exit 1; same route oracle selected one test and five disarmed invalid-route cases failed | +| Same route oracle without `--disarm-route` | Local integration control restored | Exit 0; one selected test passed | +| Official checkout `uv sync --extra dev --python 3.13.15`, then unchanged CI command `python -m pytest tests/ -v --cov=claude_agent_sdk --cov-report=xml` | Unchanged upstream tests; development installation via uv | Exit 0; 1,587 passed and six skipped in 28.46 seconds; Linux, CPython 3.13.15, MCP 2.2.0, AnyIO 4.15.1, pytest 9.1.1 | + +The upstream run used the exact tagged source and its declared developer extra. +The test command is from the pinned +[`.github/workflows/test.yml`](https://github.com/anthropics/claude-agent-sdk-python/blob/f2204bb956bab02907aaf3cb88eb9dead28eaa35/.github/workflows/test.yml). +Five skips occurred during collection; the sixth was +`TestRecompressWheel.test_zopfli_keeps_every_member`. The native `-v` output did +not include reasons for the five collection skips. The official provider E2E, +Docker E2E and example jobs were not run. These upstream unit tests do not attest +OmniRoute acceptance. The standalone script's observed default Python was +3.14.7; that is distinct from the upstream CI-aligned 3.13.15 test environment. + +## Corrections and verification paths + +1. **Script locking:** the installed modern-python skill said PEP 723 scripts + have no lockfile. Installed uv 0.12.17 `lock --help`, the official script guide + and the returned successful native lock establish support for a script lock. +2. **Native resume argv:** the first local fixture assumed `--resume UUID`. + Pinned `subprocess_cli.py` deliberately uses `--resume=UUID` to prevent + dash-leading argument injection. The test now checks the actual native argv. + The runner already passed the supported `resume` option and was unchanged. +3. **Settings-read fixture scope:** the first fixture rejected every + `Path.read_text` call, also blocking Python's package-version metadata read. + It now rejects reads of the supplied caller MCP configuration specifically, + while allowing package metadata. This correction changed the test oracle. +4. **Sparse source access:** a missing local `launch.mjs` path came from the + coordinator's sparse checkout. `rtk proxy git show HEAD:bin/cli/commands/launch.mjs` + recovered the tracked primary blob. Missing worktree files are not evidence + that the upstream capability is absent. +5. **Gateway login boundary:** a base URL alone does not implement the selected + upstream launcher semantics. The runner now adopts the documented keyless + loopback sentinel and native-auth key filtering before connecting. Native + credentials are not carried into the gateway child by accident. The parent + retains its first bounded failed live attempt separately, including unknown + usage when no native usage result was returned. +6. **Synthetic session identity publication:** the first publication check + rejected the test's literal synthetic UUID as a possible private session + identifier. The fixture now constructs its deterministic identity with + `uuid.uuid5`; no native session identifier was used or copied. The publication + guard remains unchanged. + +## Usage and lifecycle limits + +The local suite exercises a native-client-shaped synthetic control fixture, +not a real child-process or provider cancellation claim. Timeout/interrupt and +fresh successful synthetic work remain separate from native session resume. +The unchanged upstream suite covers its own native transport lifecycle cases. + +Last native usage fields and the latest model-usage snapshot stay separate; +cumulative snapshots and cache subsets are not summed. Gateway-supplied counts +must be corroborated before treating them as provider measurements or native +cache savings. A reported native list cost is not billing, and missing counters +remain unknown. Executor/advisor totals require independent reconciliation. + +The publication decision remains a bounded integration trial. Full installed +skill coverage, role/subagent routing, MCP/plugin/hooks, recovery and the sealed +three-arm SDK comparison gate are not established by these tests. diff --git a/examples/claude-runtime-sdk/worker.py b/examples/claude-runtime-sdk/worker.py new file mode 100644 index 000000000..4fa7c3745 --- /dev/null +++ b/examples/claude-runtime-sdk/worker.py @@ -0,0 +1,497 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.13" +# dependencies = ["claude-agent-sdk==0.2.162"] +# /// +"""A worker-scoped OmniRoute transport for the official Claude Agent SDK. + +Source: anthropics/claude-agent-sdk-python v0.2.162, +f2204bb956bab02907aaf3cb88eb9dead28eaa35, client.py and types.py. +The SDK, not this script, owns the agent loop, tools, context and session store. +""" + +from __future__ import annotations + +import argparse +import copy +import hashlib +import importlib.metadata +import json +import math +import os +import re +import sys +import uuid +from dataclasses import dataclass, field +from pathlib import Path +from typing import Any, Literal +from urllib.parse import urlsplit + +import anyio +from claude_agent_sdk import ( + AssistantMessage, + ClaudeAgentOptions, + ClaudeSDKClient, + ResultMessage, + SystemMessage, + ToolResultBlock, + ToolUseBlock, + UserMessage, +) + +SDK_VERSION = "0.2.162" +SDK_COMMIT = "f2204bb956bab02907aaf3cb88eb9dead28eaa35" +OMNIROUTE_LAUNCH_COMMIT = "2f42a9ac19d1a247ec9ce5473b790843724b3061" +DEFAULT_MODEL = "dva/claude-opus-5-max" +DEFAULT_GATEWAY = "http://127.0.0.1:20128" +MODEL_ID = re.compile(r"(?:[A-Za-z0-9_.:-]+/)?claude-[A-Za-z0-9_.:-]+\Z") +USAGE_COUNTERS = { + "input_tokens", + "output_tokens", + "cache_creation_input_tokens", + "cache_read_input_tokens", + "reasoning_tokens", +} +MODEL_COUNTERS = { + "inputTokens", + "outputTokens", + "cacheReadInputTokens", + "cacheCreationInputTokens", + "webSearchRequests", + "costUSD", + "contextWindow", + "maxOutputTokens", +} + + +def loopback_root(value: str) -> str: + """Claude's Anthropic transport appends /v1/messages to this root.""" + try: + parts = urlsplit(value) + port = parts.port + except ValueError: + raise ValueError("invalid gateway root") from None + if ( + parts.scheme not in {"http", "https"} + or parts.hostname not in {"127.0.0.1", "localhost", "::1"} + or port is None + or parts.username is not None + or parts.password is not None + or parts.path not in {"", "/"} + or parts.query + or parts.fragment + ): + raise ValueError("gateway must be a credential-free loopback root with a port") + return value.rstrip("/") + + +def build_options(args: argparse.Namespace) -> ClaudeAgentOptions: + """Compose SDK options; opaque explicit gateway credentials stay in memory.""" + if "CLAUDE_CODE_EFFORT_LEVEL" in os.environ: + raise ValueError( + "inherited CLAUDE_CODE_EFFORT_LEVEL must be unset before launch" + ) + if not MODEL_ID.fullmatch(args.model): + raise ValueError("worker model must be an explicit Claude-family model ID") + if not args.cwd.is_dir(): + raise ValueError("worker cwd must be an existing directory") + if args.resume is not None: + try: + uuid.UUID(args.resume) + except ValueError: + raise ValueError("resume must be a native session UUID") from None + if args.skill is None or args.skill == ["all"]: + skills: list[str] | Literal["all"] = "all" + elif "all" in args.skill: + raise ValueError("select all or exact skill names, not both") + else: + skills = args.skill + for path in args.plugin or []: + if not path.is_dir(): + raise ValueError("local plugin path must be an existing directory") + if args.mcp_config is not None and not args.mcp_config.is_file(): + raise ValueError("MCP configuration path must be an existing file") + gateway = loopback_root(args.gateway) + auth_token = "omniroute-no-auth" + if args.gateway_token_env is not None: + if not re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", args.gateway_token_env): + raise ValueError("gateway-token-env must name an application environment variable") + if args.gateway_token_env.startswith("ANTHROPIC_"): + raise ValueError("use a gateway-specific token binding, separate from native Anthropic credentials") + auth_token = os.environ.get(args.gateway_token_env) + if not auth_token or not auth_token.strip(): + raise ValueError("the explicit gateway token environment binding is missing or empty") + return ClaudeAgentOptions( + system_prompt={"type": "preset", "preset": "claude_code"}, + model=args.model, + effort="max", + cwd=args.cwd.resolve(), + # OmniRoute buildClaudeEnv, pinned above; retain native compaction policy. + env={ + "ANTHROPIC_BASE_URL": gateway, + "ANTHROPIC_AUTH_TOKEN": auth_token, + "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1", + }, + setting_sources=args.setting_source or ["user", "project"], + skills=skills, + plugins=[ + {"type": "local", "path": str(p.resolve())} for p in args.plugin or [] + ], + mcp_servers=str(args.mcp_config.resolve()) if args.mcp_config else {}, + allowed_tools=args.allow_tool or [], + permission_mode=args.permission_mode, + max_turns=args.max_turns, + resume=args.resume, + fork_session=args.fork_session, + ) + + +def prepare_worker_environment() -> int: + """Strip native Anthropic env only in this standalone worker process. + + The SDK merges options.env onto os.environ and cannot delete inherited keys. + OmniRoute's native buildClaudeEnv uses the same ANTHROPIC_* key filter. + No credential value is inspected, returned or written to disk. + """ + keys = [key for key in os.environ if key.startswith("ANTHROPIC_")] + for key in keys: + del os.environ[key] + return len(keys) + + +def preflight(options: ClaudeAgentOptions) -> dict[str, Any]: + """Small configuration evidence; no request, activation or identity claim.""" + if importlib.metadata.version("claude-agent-sdk") != SDK_VERSION: + raise ValueError("installed SDK does not match the script pin") + return { + "evidence_class": "configuration_only", + "sdk_version": SDK_VERSION, + "sdk_commit": SDK_COMMIT, + "omniroute_launch_commit": OMNIROUTE_LAUNCH_COMMIT, + "python_version": sys.version.split()[0], + "requested_model": options.model, + "provider_identity_verified": False, + "effort": options.effort, + "system_prompt_preset": "claude_code", + "tools_unrestricted": options.tools is None, + "skills": options.skills, + "setting_sources": options.setting_sources, + "plugin_count": len(options.plugins), + "mcp_config_explicit": isinstance(options.mcp_servers, str), + "gateway_loopback": True, + "gateway_port": urlsplit(options.env["ANTHROPIC_BASE_URL"]).port, + "gateway_auth_injected": "ANTHROPIC_AUTH_TOKEN" in options.env, + "gateway_model_discovery": True, + "cwd_exists": Path(options.cwd).is_dir(), + "resumed": options.resume is not None, + "fork_session": options.fork_session, + "max_turns": options.max_turns, + "permission_mode": options.permission_mode, + } + + +def numeric_counters(value: Any, keys: set[str]) -> dict[str, int | float] | None: + if not isinstance(value, dict): + return None + return { + key: number + for key, number in value.items() + if key in keys + and isinstance(number, (int, float)) + and not isinstance(number, bool) + and math.isfinite(number) + } + + +@dataclass +class Observation: + """Last native snapshots, never summed with cache subsets or prior turns.""" + + session_id: str | None = None + status: str = "running" + result_count: int = 0 + tool_calls: dict[str, int] = field(default_factory=dict) + tool_events: list[dict[str, Any]] = field(default_factory=list) + tool_results: list[dict[str, Any]] = field(default_factory=list) + init: dict[str, Any] = field(default_factory=dict) + result: str | None = None + last_result: dict[str, Any] | None = None + usage: dict[str, Any] | None = None + model_usage: dict[str, Any] | None = None + native_cost_usd: float | None = None + interrupt_sent: bool = False + + def observe(self, message: Any) -> None: + if isinstance(message, SystemMessage) and message.subtype == "init": + self.session_id = message.data.get("session_id") + for key in ("tools", "skills", "agents", "mcp_servers"): + values = message.data.get(key) + if isinstance(values, list): + self.init[key + "_count"] = len(values) + self.init[key] = [ + value + if isinstance(value, str) + else { + field: value[field] + for field in ("name", "status") + if field in value and isinstance(value[field], str) + } + for value in values + if isinstance(value, (str, dict)) + ] + self.init["reported_model"] = message.data.get("model") + self.init["reported_cli_version"] = message.data.get("claude_code_version") + elif isinstance(message, AssistantMessage): + for block in message.content: + if isinstance(block, ToolUseBlock): + self.tool_calls[block.name] = self.tool_calls.get(block.name, 0) + 1 + event = {"id": block.id, "name": block.name} + if block.name == "Skill" and isinstance( + block.input.get("skill"), str + ): + event["skill"] = block.input["skill"] + self.tool_events.append(event) + elif isinstance(message, UserMessage) and isinstance(message.content, list): + for block in message.content: + if isinstance(block, ToolResultBlock): + self.tool_results.append( + {"tool_use_id": block.tool_use_id, "is_error": block.is_error} + ) + elif isinstance(message, ResultMessage): + self.result_count += 1 + self.session_id = message.session_id + self.result = message.result + self.status = "native_error" if message.is_error else "completed" + self.last_result = { + "subtype": message.subtype, + "is_error": message.is_error, + "num_turns": message.num_turns, + "duration_ms": message.duration_ms, + "duration_api_ms": message.duration_api_ms, + "terminal_reason": message.terminal_reason, + "stop_reason": message.stop_reason, + "api_error_status": message.api_error_status, + "error_count": len(message.errors or []), + } + self.usage = numeric_counters(message.usage, USAGE_COUNTERS) + self.model_usage = ( + None + if message.model_usage is None + else { + model: numeric_counters(counters, MODEL_COUNTERS) + for model, counters in message.model_usage.items() + } + ) + self.native_cost_usd = message.total_cost_usd + + def summary(self) -> dict[str, Any]: + result_bytes = self.result.encode() if self.result is not None else None + return { + "evidence_class": "local_sdk_runtime_observation", + "status": self.status, + "session_id": self.session_id, + "init": copy.deepcopy(self.init), + "tool_calls": dict(self.tool_calls), + "tool_events": copy.deepcopy(self.tool_events), + "tool_results": copy.deepcopy(self.tool_results), + "result_count": self.result_count, + "last_result": copy.deepcopy(self.last_result), + "result_bytes": len(result_bytes) if result_bytes is not None else None, + "result_sha256": hashlib.sha256(result_bytes).hexdigest() + if result_bytes is not None + else None, + "interrupt_sent": self.interrupt_sent, + "usage_last_native_result": copy.deepcopy(self.usage), + "model_usage_latest_session_snapshot": copy.deepcopy(self.model_usage), + "usage_snapshots_summed": False, + "cache_counters_added_to_input": False, + "native_reported_cost_usd": self.native_cost_usd, + "billing_cost_usd": None, + "provider_identity_verified": False, + } + + +async def run_worker( + options: ClaudeAgentOptions, + prompt: str, + *, + timeout: float, + interrupt_after: float | None = None, + client_factory: Any = ClaudeSDKClient, +) -> Observation: + """Use the native client lifecycle and interrupt; no retry or model loop.""" + observation = Observation() + deadline = anyio.current_time() + timeout + + async def timed_interrupt(client: Any) -> None: + assert interrupt_after is not None + await anyio.sleep(interrupt_after) + await client.interrupt() + observation.interrupt_sent = True + + try: + # SDK cleanup is shielded and terminates/kills its own CLI subprocess. + with anyio.fail_after(timeout + 5): + async with client_factory(options=options) as client: + with anyio.move_on_after( + max(0, deadline - anyio.current_time()) + ) as scope: + async with anyio.create_task_group() as group: + if interrupt_after is not None: + group.start_soon(timed_interrupt, client) + await client.query(prompt) + async for message in client.receive_response(): + observation.observe(message) + group.cancel_scope.cancel() + if scope.cancel_called: + observation.status = "timeout" + with anyio.move_on_after(4, shield=True): + await client.interrupt() + observation.interrupt_sent = True + async for message in client.receive_response(): + observation.observe(message) + observation.status = "timeout" + elif observation.last_result is None: + observation.status = "missing_native_result" + elif observation.last_result["terminal_reason"] in { + "aborted_streaming", + "aborted_tools", + }: + observation.status = "interrupted" + elif observation.last_result["terminal_reason"] not in { + None, + "completed", + }: + observation.status = "native_incomplete" + except TimeoutError: + observation.status = "timeout" + except Exception as error: + # Native exception text can contain prompts, paths or credentials. + observation.status = "sdk_error" + observation.last_result = {"exception_type": type(error).__name__} + return observation + + +def parser() -> argparse.ArgumentParser: + cli = argparse.ArgumentParser(description=__doc__) + cli.add_argument( + "--preflight", action="store_true", help="configuration only; no model request" + ) + cli.add_argument("--cwd", type=Path, default=Path.cwd()) + cli.add_argument( + "--gateway", + default=DEFAULT_GATEWAY, + help="loopback Anthropic root, without /v1", + ) + cli.add_argument( + "--gateway-token-env", + help="optional application env binding for gateway auth; values are never printed", + ) + cli.add_argument( + "--model", + default=DEFAULT_MODEL, + help="explicit advertised Claude-family candidate", + ) + cli.add_argument( + "--setting-source", action="append", choices=["user", "project", "local"] + ) + cli.add_argument( + "--skill", action="append", help="all or repeat exact task-matched skill names" + ) + cli.add_argument( + "--plugin", type=Path, action="append", help="selected local plugin directory" + ) + cli.add_argument( + "--mcp-config", + type=Path, + help="native MCP JSON path; contents are not read here", + ) + cli.add_argument( + "--allow-tool", + action="append", + help="native permission auto-approval, not a tool restriction", + ) + cli.add_argument( + "--permission-mode", + default="dontAsk", + choices=["default", "dontAsk", "acceptEdits", "plan", "auto"], + ) + cli.add_argument("--max-turns", type=int, default=12) + cli.add_argument("--timeout", type=float, default=300) + cli.add_argument( + "--interrupt-after", + type=float, + help="send one native interrupt after this many seconds", + ) + cli.add_argument( + "--resume", help="same native session UUID and cwd; no implicit resubmission" + ) + cli.add_argument("--fork-session", action="store_true") + cli.add_argument( + "--result-output", + type=Path, + help="new private 0600 file for returned text; summary stdout omits text", + ) + return cli + + +def main() -> int: + args = parser().parse_args() + try: + if not math.isfinite(args.timeout) or args.timeout <= 0 or args.max_turns <= 0: + raise ValueError("timeout and max-turns must be positive") + if ( + args.interrupt_after is not None + and not 0 < args.interrupt_after < args.timeout + ): + raise ValueError( + "interrupt-after must be positive and smaller than timeout" + ) + options = build_options(args) + configuration = preflight(options) + if args.preflight: + print(json.dumps(configuration, sort_keys=True)) + return 0 + prompt = sys.stdin.read() + if not prompt.strip(): + raise ValueError("a non-empty prompt is required on stdin") + if args.result_output is not None and args.result_output.exists(): + raise ValueError("result-output must be a new private file") + # This CLI process is the owned worker child, not the native coordinator. + configuration["native_anthropic_env_keys_removed"] = prepare_worker_environment() + observation = anyio.run( + lambda: run_worker( + options, + prompt, + timeout=args.timeout, + interrupt_after=args.interrupt_after, + ) + ) + if args.result_output is not None and observation.result is not None: + flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL + try: + with os.fdopen( + os.open(args.result_output, flags, 0o600), "w" + ) as output: + output.write(observation.result) + except OSError: + # Keep native usage and identifiers even when artifact writing fails. + observation.status = "result_artifact_error" + print( + json.dumps( + {"configuration": configuration, "observation": observation.summary()}, + sort_keys=True, + ) + ) + return 0 if observation.status == "completed" else 1 + except (ValueError, OSError) as error: + # Configuration errors are authored here; OS errors may carry private paths. + message = str(error) if isinstance(error, ValueError) else type(error).__name__ + print( + json.dumps({"status": "preflight_failed", "error": message}, sort_keys=True) + ) + return 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/examples/claude-runtime-sdk/worker.py.lock b/examples/claude-runtime-sdk/worker.py.lock new file mode 100644 index 000000000..d596fd1cf --- /dev/null +++ b/examples/claude-runtime-sdk/worker.py.lock @@ -0,0 +1,610 @@ +version = 1 +revision = 3 +requires-python = ">=3.13" +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version < '3.14'", +] + +[manifest] +requirements = [{ name = "claude-agent-sdk", specifier = "==0.2.162" }] + +[[package]] +name = "annotated-types" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" }, +] + +[[package]] +name = "anyio" +version = "4.15.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.15'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/d2/f4d173e22df740bc37b1db102b386ba719b66e95b0f0d751f556b387e6d2/anyio-4.15.1.tar.gz", hash = "sha256:9f28306018cbd6d329e64a36d58256edff76dd996fe423bc957326e578b82a94", size = 276966, upload-time = "2026-09-05T10:42:39.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b8/4bd346e22b28902df4d651910f5242c28d84e4a5c2435ca5c3f797ed7e2e/anyio-4.15.1-py3-none-any.whl", hash = "sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101", size = 132079, upload-time = "2026-09-05T10:42:37.923Z" }, +] + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "cffi" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/f4/035513d4117049066b4779dc3b7c0c0fdad175fa13731c9f4003f1cd1478/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e", size = 194248, upload-time = "2026-08-03T21:19:59.399Z" }, + { url = "https://files.pythonhosted.org/packages/76/af/2aeb4dbb5fc41a04161ae9ff1518de7cec08e164f44a8ce6a4cf7fd2cd1d/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c", size = 196908, upload-time = "2026-08-03T21:20:00.746Z" }, + { url = "https://files.pythonhosted.org/packages/a7/46/2e5fdde8555706dd98139a910ca11be02809f3f605ce956f655d0214e100/cffi-2.1.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6", size = 184805, upload-time = "2026-08-03T21:20:02.02Z" }, + { url = "https://files.pythonhosted.org/packages/55/41/4c7042f317b9217502988f0873af87e16ad606dc20f84e546e3e6ce9764c/cffi-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971", size = 184764, upload-time = "2026-08-03T21:20:03.141Z" }, + { url = "https://files.pythonhosted.org/packages/43/1f/1c3d90d91811c8f86ced9ed637956c54bfe5b79ca98fe976d7f8c8979f6b/cffi-2.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c", size = 214722, upload-time = "2026-08-03T21:20:04.377Z" }, + { url = "https://files.pythonhosted.org/packages/37/6f/3b5ce4c3b2192d250f04908f2bfd91ef34552ec8f7716a5d4abdb8d67bb2/cffi-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125", size = 222369, upload-time = "2026-08-03T21:20:05.544Z" }, + { url = "https://files.pythonhosted.org/packages/02/10/4b3c75dde3d9663c9e02ba05c2668b954f671d4bbe346413ca8c696b295a/cffi-2.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264", size = 210175, upload-time = "2026-08-03T21:20:06.75Z" }, + { url = "https://files.pythonhosted.org/packages/df/62/14f74b9543e605d17701dc797b815958b8bb70b7624ce1b832ddad48ed6c/cffi-2.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3", size = 208670, upload-time = "2026-08-03T21:20:08.04Z" }, + { url = "https://files.pythonhosted.org/packages/95/95/86342356ff5953b3fb06f7ef7c5bee212d45e770abc7218d451b9148313c/cffi-2.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2", size = 221824, upload-time = "2026-08-03T21:20:09.274Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ff/7b3429ff53aafe931ed8a5fc69f481bbef7ba6de87ddcbb63d08f483f613/cffi-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b", size = 225148, upload-time = "2026-08-03T21:20:10.7Z" }, + { url = "https://files.pythonhosted.org/packages/34/34/a95870b9221e09cf4f2ce3178b1a210abdfe63a1bd357da940418d7b8d15/cffi-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7", size = 223564, upload-time = "2026-08-03T21:20:12.165Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/839b50531021a647fb5e929f72cf97bc1ff702b5472166164b5b6e76b851/cffi-2.1.1-cp313-cp313-win32.whl", hash = "sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac", size = 175263, upload-time = "2026-08-03T21:20:13.559Z" }, + { url = "https://files.pythonhosted.org/packages/60/a6/8b149b2c3f2e11aaa1618ef64500b45f50f22c57a977a4dff1aff1f91042/cffi-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d", size = 185688, upload-time = "2026-08-03T21:20:14.69Z" }, + { url = "https://files.pythonhosted.org/packages/01/9a/11f687cb39d6a3504060d5242f04f48c735afb4d3d533958a20594890cb2/cffi-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973", size = 180078, upload-time = "2026-08-03T21:20:15.917Z" }, + { url = "https://files.pythonhosted.org/packages/d3/7b/d6bbf82b8b96e7391438898c42f5bd96dd02030fd5b64937d248220003e2/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c", size = 194064, upload-time = "2026-08-03T21:20:17.148Z" }, + { url = "https://files.pythonhosted.org/packages/94/e6/bcc91b283be94735e268487a054004f0aa19947b6348fa367db53230abc8/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb", size = 196720, upload-time = "2026-08-03T21:20:18.268Z" }, + { url = "https://files.pythonhosted.org/packages/d9/99/c4b0c17cacdc9c3b8f280026286a9826d6a208c0f047591a3c3ce99b91fd/cffi-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54", size = 184964, upload-time = "2026-08-03T21:20:19.708Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a9/9db617d05d7367c1ad0ab00b3aa6e6f9281edd689b4ee9ea0e5a84e89c97/cffi-2.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72", size = 184962, upload-time = "2026-08-03T21:20:20.833Z" }, + { url = "https://files.pythonhosted.org/packages/67/b8/b42132ca113dc567d37684437b46ca1dafc885902b02a110a02d5b511857/cffi-2.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1", size = 222328, upload-time = "2026-08-03T21:20:22.118Z" }, + { url = "https://files.pythonhosted.org/packages/80/10/c5c0cbf0a657aecf59ef511409734230bf556f05a0d6c9eed7aa5c0a0166/cffi-2.1.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062", size = 209985, upload-time = "2026-08-03T21:20:23.401Z" }, + { url = "https://files.pythonhosted.org/packages/d5/6c/bfa0b87b03b9238148beca990292843c9396ba069b54496596594173de7b/cffi-2.1.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03", size = 208530, upload-time = "2026-08-03T21:20:24.628Z" }, + { url = "https://files.pythonhosted.org/packages/e9/02/4e7d553a7ac4b4238b38b3c1b80d486e9d4436f8d2acbf87a0997fe3f402/cffi-2.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96", size = 221525, upload-time = "2026-08-03T21:20:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/82/1d/a4aaf9babd75acb4d5f223bff71533bee748dd770a382619a798960ee9ba/cffi-2.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527", size = 225053, upload-time = "2026-08-03T21:20:26.985Z" }, + { url = "https://files.pythonhosted.org/packages/81/10/5dc0e7bdd18e22107054288283380fc97a06ae3f1656a106908d666a3c88/cffi-2.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13", size = 223213, upload-time = "2026-08-03T21:20:28.277Z" }, + { url = "https://files.pythonhosted.org/packages/0b/e9/d0061c364cde06ee43168a0d076ac1da512cbc380d44767b844ba34fe2b6/cffi-2.1.1-cp314-cp314-win32.whl", hash = "sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c", size = 177682, upload-time = "2026-08-03T21:20:44.288Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1c3e01e3ba14c39f6d10bfbac52753b7e22259e38088e5cfe1d704918690/cffi-2.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48", size = 187949, upload-time = "2026-08-03T21:20:45.623Z" }, + { url = "https://files.pythonhosted.org/packages/87/5b/da4e39efe18eeb89cf580ea9cfc66b6a7c3eadb808fc0cc1d3a295cb5a5d/cffi-2.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836", size = 182947, upload-time = "2026-08-03T21:20:46.955Z" }, + { url = "https://files.pythonhosted.org/packages/23/59/40338bf421c5accea1d45158170c87006ef1cd371b05c077e76476949728/cffi-2.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3", size = 188504, upload-time = "2026-08-03T21:20:29.495Z" }, + { url = "https://files.pythonhosted.org/packages/7d/47/5ecf1023850036e674c77ec4de86182d309ae344e39e7cba984b7df5d647/cffi-2.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2", size = 188259, upload-time = "2026-08-03T21:20:31.291Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9c/92934c3bea9f785b23eba304538c0b4d37a2a96d2431eb3a1bc87a11aa19/cffi-2.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94", size = 223864, upload-time = "2026-08-03T21:20:32.571Z" }, + { url = "https://files.pythonhosted.org/packages/4d/45/ba4c93527bc38616a8bd36488acb69a2212d60486794f0c1f318949bbb76/cffi-2.1.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc", size = 211538, upload-time = "2026-08-03T21:20:33.808Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/b6ef565e452acb932fb0cb5443f44a78efbd1233e566f02b5a83855e9115/cffi-2.1.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29", size = 210688, upload-time = "2026-08-03T21:20:34.974Z" }, + { url = "https://files.pythonhosted.org/packages/9a/95/eff5f0cee78d2eabc7eebffec40d3fc1876b5f3c95582e018bb4b99601f2/cffi-2.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676", size = 223803, upload-time = "2026-08-03T21:20:36.564Z" }, + { url = "https://files.pythonhosted.org/packages/fa/01/579d39fb8bef00a335a23d83757b44feb24cd6345a2c451b64cb67b9c362/cffi-2.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e", size = 226763, upload-time = "2026-08-03T21:20:37.816Z" }, + { url = "https://files.pythonhosted.org/packages/8d/b0/0b44f47c60b01b57b6e2bbd92343f13a85a1d93bc46ccf6e47e244acd99c/cffi-2.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f", size = 225688, upload-time = "2026-08-03T21:20:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d2/3b7176cb570a1d3e27faf67b72f591af508036e0d8b2be2ef9af9e8c84bb/cffi-2.1.1-cp314-cp314t-win32.whl", hash = "sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4", size = 182868, upload-time = "2026-08-03T21:20:40.388Z" }, + { url = "https://files.pythonhosted.org/packages/56/78/31f00c1bcd97c9bbf55f1bfdf5bc809a5de8887473e90bb9960dca825e80/cffi-2.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e", size = 194104, upload-time = "2026-08-03T21:20:41.725Z" }, + { url = "https://files.pythonhosted.org/packages/7b/1b/58496f2ed0a35de575250c02a43ab3cc2c04d494a88fed31c1cabc0fd176/cffi-2.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5", size = 186402, upload-time = "2026-08-03T21:20:43.042Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8f/9ebe220eab48a093d1a5a5e339ab0dc7316eef3bb04d63c42f0251b61f50/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d", size = 194043, upload-time = "2026-08-03T21:20:48.179Z" }, + { url = "https://files.pythonhosted.org/packages/ff/69/844bad3ece306c4782c2ecb93597035b6690d48704b803914c199da1e8b3/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b", size = 196737, upload-time = "2026-08-03T21:20:49.457Z" }, + { url = "https://files.pythonhosted.org/packages/1b/8a/af668013284634733f02d683458a0728739c7d6ddb5e14cb0c20832266fe/cffi-2.1.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4", size = 184933, upload-time = "2026-08-03T21:20:50.639Z" }, + { url = "https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8", size = 185002, upload-time = "2026-08-03T21:20:52.173Z" }, + { url = "https://files.pythonhosted.org/packages/e2/31/9e1313b0a6e30e91b3b3d3fff51ae99c857c07738e3afcce1f7334e1b7ab/cffi-2.1.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6", size = 222271, upload-time = "2026-08-03T21:20:53.462Z" }, + { url = "https://files.pythonhosted.org/packages/50/e3/f6234a833e6e08c7007003074723c406559eecf9b48dfc97471e5a8eb7a0/cffi-2.1.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80", size = 209919, upload-time = "2026-08-03T21:20:54.783Z" }, + { url = "https://files.pythonhosted.org/packages/0d/fc/5f74e293fced6edb51af3a46c4ccf6c23c9943774ecb375ddbd522c76add/cffi-2.1.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779", size = 208529, upload-time = "2026-08-03T21:20:56.066Z" }, + { url = "https://files.pythonhosted.org/packages/44/16/29e6d01b388bef055ecd6ca8244b3f4d336bd09e92d5d892187b9601084e/cffi-2.1.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399", size = 221630, upload-time = "2026-08-03T21:20:57.336Z" }, + { url = "https://files.pythonhosted.org/packages/a4/18/fa7f1f6857d5eb88a4ca99ffcbfb7c387a287ccc154c64a73e86314745d7/cffi-2.1.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688", size = 225134, upload-time = "2026-08-03T21:20:58.675Z" }, + { url = "https://files.pythonhosted.org/packages/e0/9f/e8e3dfa04a1b4c241f8c91faacad872b4d4efd051d49764ad4e2fd4b9fea/cffi-2.1.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7", size = 223197, upload-time = "2026-08-03T21:20:59.968Z" }, + { url = "https://files.pythonhosted.org/packages/f8/7e/8debeb04f1ab9fe2a6963964cd6f1aaf7192627b83926586a6a4e089c9fa/cffi-2.1.1-cp315-cp315-win32.whl", hash = "sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac", size = 177683, upload-time = "2026-08-03T21:21:14.901Z" }, + { url = "https://files.pythonhosted.org/packages/e0/31/5158704cc474ab65c1647932e88be78dc0873f47130e253be38bcaf13d01/cffi-2.1.1-cp315-cp315-win_amd64.whl", hash = "sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960", size = 187897, upload-time = "2026-08-03T21:21:16.108Z" }, + { url = "https://files.pythonhosted.org/packages/cc/4b/b3a2da8570c704ffc0f9762cdc3ec0f02c8573798e0b5cf7f11c82bbb70f/cffi-2.1.1-cp315-cp315-win_arm64.whl", hash = "sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1", size = 182935, upload-time = "2026-08-03T21:21:17.271Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ef/5443574510a1207e6f6bc38ba6e1f1de36cb48fef07b2728bb896a21f430/cffi-2.1.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc", size = 188464, upload-time = "2026-08-03T21:21:01.163Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ae/a56fa8c4686ad50e148fcbc8d3ae0d03915ff5c30d795058988c24118cef/cffi-2.1.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab", size = 188262, upload-time = "2026-08-03T21:21:02.382Z" }, + { url = "https://files.pythonhosted.org/packages/53/b2/6187f46f2912276a3ae284076109cc5c8680482f11f766ccf26db4a86427/cffi-2.1.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e", size = 223779, upload-time = "2026-08-03T21:21:03.553Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f6/c3ad28bd19f77047a03084424fbd4cbe997303267c14423737324be0385d/cffi-2.1.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358", size = 211520, upload-time = "2026-08-03T21:21:04.863Z" }, + { url = "https://files.pythonhosted.org/packages/a0/cd/ccac9013a5bd9fd764de118674ab9c805b5ca10c19270d90ee273f8b2240/cffi-2.1.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231", size = 210673, upload-time = "2026-08-03T21:21:06.223Z" }, + { url = "https://files.pythonhosted.org/packages/52/86/2976131c639aead931c5bee5aba67e4b09fbeb8018b6f282f70803f923a7/cffi-2.1.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6", size = 223835, upload-time = "2026-08-03T21:21:07.539Z" }, + { url = "https://files.pythonhosted.org/packages/ac/0c/33a7aeab2f9c76918c52e084beb39c570db3588133412929e8ec06fab90b/cffi-2.1.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94", size = 226705, upload-time = "2026-08-03T21:21:08.774Z" }, + { url = "https://files.pythonhosted.org/packages/e3/26/2cde30fdde421130bfc18f70395731a6e6b2053c6a1978a5258ff04e72fa/cffi-2.1.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5", size = 225539, upload-time = "2026-08-03T21:21:09.911Z" }, + { url = "https://files.pythonhosted.org/packages/6d/cd/a361394c94b2129d604bb846f624a8e88255a3ee33129c434a00d715e64f/cffi-2.1.1-cp315-cp315t-win32.whl", hash = "sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66", size = 182707, upload-time = "2026-08-03T21:21:11.226Z" }, + { url = "https://files.pythonhosted.org/packages/9b/b5/ba2b299993c26577d529b6ae29841f9e15b9fcf004d65f423f4fcf94ade9/cffi-2.1.1-cp315-cp315t-win_amd64.whl", hash = "sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3", size = 193772, upload-time = "2026-08-03T21:21:12.39Z" }, + { url = "https://files.pythonhosted.org/packages/aa/29/35e016098c814cd93de9cd320c66b5bfba14dc6ecedd3cb518fa7c408c69/cffi-2.1.1-cp315-cp315t-win_arm64.whl", hash = "sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692", size = 186360, upload-time = "2026-08-03T21:21:13.636Z" }, +] + +[[package]] +name = "claude-agent-sdk" +version = "0.2.162" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "jsonschema" }, + { name = "mcp" }, + { name = "sniffio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/a3/d31886d0723593228797c96eb54d07a19e561931a2771ed40b4a105bedc9/claude_agent_sdk-0.2.162.tar.gz", hash = "sha256:e4cf92f04f934d3b87d42be9ecbeb75c1a3d487a8dc8a299f7fed1ad9d0b476f", size = 365167, upload-time = "2026-09-29T20:06:54.593Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/b6/ec37e32cb0782977e80cd00338f5073f150d6ecfa568e9fa1a1dd5c9eed3/claude_agent_sdk-0.2.162-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a0d5ad6185a8bcaaff05f5648036e2484cab28bd1c2ccc474fc8969555b386f7", size = 92700771, upload-time = "2026-09-29T20:06:59.661Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/1165688243cbf90d3532f509ea65bc337c3ba7f8229e26d7297e00a6ec2b/claude_agent_sdk-0.2.162-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:faab97b03f04f9c3deb58ad85a0410404d40b6efb5547c9defc4fa986642fced", size = 97130408, upload-time = "2026-09-29T20:07:06.243Z" }, + { url = "https://files.pythonhosted.org/packages/05/41/f0addb831c3aefbc02c811ef7415e89e889d1bc2ae976eb935c508c91c0d/claude_agent_sdk-0.2.162-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:332cfb5eb9190fc8de1ad427753417d7c345264e9d2bd2ffa312afcc2f5cf766", size = 102183342, upload-time = "2026-09-29T20:07:14.279Z" }, + { url = "https://files.pythonhosted.org/packages/d2/33/8a7acd75405d0cfde96c26219dbbac050aa23416ceefd5f62cf7aecfc22d/claude_agent_sdk-0.2.162-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:673598c9916f5f4d03ff49ab3128f856f0c6508135e8e258838fc3b6f7aafa49", size = 102525631, upload-time = "2026-09-29T20:07:23.411Z" }, +] + +[[package]] +name = "click" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/0e/7fa0ef50764b67090eca4114772a2abf8b6148198475e54c660b97caeee6/click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34", size = 382235, upload-time = "2026-08-26T13:33:14.56Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", size = 125251, upload-time = "2026-08-26T13:33:12.928Z" }, +] + +[[package]] +name = "cryptography" +version = "50.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/56/d194340cc4a57535e82e1bee9e89667ac4b7c13b5d3f59686deae3094dd5/cryptography-50.0.2-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:fa8f5efb344d6908a1ce62f4a24e2e5780f825d6f53f5f50ec5ffacac72936cb", size = 3914904, upload-time = "2026-09-30T14:43:44.339Z" }, + { url = "https://files.pythonhosted.org/packages/d9/69/c9bd862c3bf43d6399c433caf002df16e2dffd4be49bdf515cda38038711/cryptography-50.0.2-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:79def8d059362e7831389ed3be0ecdf58a89386e1271e35dd9f5af84e81bffd0", size = 4731146, upload-time = "2026-09-30T14:43:47.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/69/64cef1f702bf6657e0cc186ed1a2891d50d29fb41586b254e1c07adea261/cryptography-50.0.2-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:630ebfea3bf689d075f82316324ff7433dc447fe6bc1bfc76524b74b4a9567d2", size = 4719841, upload-time = "2026-09-30T14:43:49.01Z" }, + { url = "https://files.pythonhosted.org/packages/38/6b/61a3f8d8c5e1e49a6cddccafc4015cc1c0021360ab0acb4080e7a423644a/cryptography-50.0.2-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f9f6143a8c75945eb960d9eb98905a441394abfa24afaae239d514ffb2586480", size = 4738340, upload-time = "2026-09-30T14:43:50.932Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2e/7212ca32fd43dc91f2f41db20160b268098874b4c9a0e7be94d6835f5b2e/cryptography-50.0.2-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:a582ab2ae1d34f67112cadc86702774c9ea4374df6bca6afe672817203c99134", size = 5367029, upload-time = "2026-09-30T14:43:52.911Z" }, + { url = "https://files.pythonhosted.org/packages/1a/f1/b474e930c4d910328780e3940da76f5aa5cbc48ce1fc14e44d239d9ea9db/cryptography-50.0.2-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4061c0079120205fb760c58acab6443e217307dcf05e3702cf970e0689972856", size = 4753050, upload-time = "2026-09-30T14:43:55.272Z" }, + { url = "https://files.pythonhosted.org/packages/7c/52/9af10e80ac16b0fcc2123f9cbd5e7afbd0fd5075bb7a607c592258a39cda/cryptography-50.0.2-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:ac9ed99d81760c62fe89d5f0815cdfa1ba9a35141cf30f1c2d044f04b4803d2e", size = 4376724, upload-time = "2026-09-30T14:43:57.24Z" }, + { url = "https://files.pythonhosted.org/packages/71/37/6202e488cc1eb625ea110c292c6bda92823176e023f427d8d5660ce8d632/cryptography-50.0.2-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:87e9ce85beb6b328ba370cc6e6aea483c92617b4c95b1d33a49297eb662bfb04", size = 4737859, upload-time = "2026-09-30T14:43:59.541Z" }, + { url = "https://files.pythonhosted.org/packages/8f/30/e86d7d518489b0ae2497091a35287abcb1a2ce4037837a34afbe9b1d6964/cryptography-50.0.2-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:f265528741e048bce55c3463ed721fb0aa45a5888d8add8cfeccb3035451bbdc", size = 5324103, upload-time = "2026-09-30T14:44:01.901Z" }, + { url = "https://files.pythonhosted.org/packages/d3/69/2c833a049475e0a3444e94c7d0aca0aa51d166374a449b09e92ac98138de/cryptography-50.0.2-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9dab55f57c74c3cad24c323bacbbd04be4705ba6eb0d92e920b1fc4837ed5079", size = 4752576, upload-time = "2026-09-30T14:44:04.545Z" }, + { url = "https://files.pythonhosted.org/packages/6c/5d/906970b83bbfc1f5bbfb677a143c181f2801f23b6a7204a3b47c42c97e65/cryptography-50.0.2-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25784ce8b9621c90c643efb9e1e2162ab3b0224cae446ad5e70e7fcb1ce18b51", size = 4870819, upload-time = "2026-09-30T14:44:06.884Z" }, + { url = "https://files.pythonhosted.org/packages/68/e3/f2298d3bb55e0c4a91841ec4d01b3f020ba8c5fbf15ccdcc6dcf03f97025/cryptography-50.0.2-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:85d0d9a31b9098e98534226d5686b47264b95e62ce459dc2e62fdfc809f9fe93", size = 5030152, upload-time = "2026-09-30T14:44:09.443Z" }, + { url = "https://files.pythonhosted.org/packages/9a/4f/adfc442765721292fff86d314ce385d3249d22db42295c0dd057727b60f3/cryptography-50.0.2-cp311-abi3-win_amd64.whl", hash = "sha256:7afa5a6602a9f29af1f3a2965f831bae7c9d5d597b7cbb716d41ab3b7d89879c", size = 3824692, upload-time = "2026-09-30T14:44:11.671Z" }, + { url = "https://files.pythonhosted.org/packages/ce/cb/52eb3770c0d0be2702a98c6e96065ddc0a2877cf0845aa9c23397c142cd4/cryptography-50.0.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f785f6161f202ab04d8ca194158968798e480ca058943907972da5f12e2881e8", size = 3892731, upload-time = "2026-09-30T14:44:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/19/8e/aa1fc533d4546b127b45de8aa024eb5933d23eff9debfe25931e56861095/cryptography-50.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0ecbc5652bdb6fc9eaf89a7d196e20941adfe812f43bc4ca05d9150496821047", size = 4710431, upload-time = "2026-09-30T14:44:15.427Z" }, + { url = "https://files.pythonhosted.org/packages/6a/64/72bc3f75176e7e406b748a3e3830432b8c51297b38368713df04dc04898a/cryptography-50.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ab50ee449bf968271e820086f10a33d101dd060370abc10bcd22279be2656539", size = 4694824, upload-time = "2026-09-30T14:44:17.69Z" }, + { url = "https://files.pythonhosted.org/packages/4e/c6/62c77550edfa5ca3f14bf44a1e6739b9fa09d6e998a11d97ed8213bccc98/cryptography-50.0.2-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:a9f7355e6fab51f6c369b86fb7571cffa05edee2c2121e0380a37fb9ac1cd5c1", size = 4716967, upload-time = "2026-09-30T14:44:19.661Z" }, + { url = "https://files.pythonhosted.org/packages/f4/37/cce70f150c432914460157a6ecc161752e053aa5ec0ef3b3f7dc6e31039a/cryptography-50.0.2-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:94e5e9f108ee10471288214d3d233fbfbb492840a8457eb85178d643ddeb32c7", size = 5328676, upload-time = "2026-09-30T14:44:21.744Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9a/6f2f0304d634ceafdeaf23e84537336664ac419b5d07611675c2ad3f6b7a/cryptography-50.0.2-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:241449bf940a5d27309bd317e6f9a2af6932113818bb2b8f5c59ddc7ef16da18", size = 4727698, upload-time = "2026-09-30T14:44:24.178Z" }, + { url = "https://files.pythonhosted.org/packages/1d/de/66bcf9244d118663b2e1aaded8990f4640e3d7b7411870a5765f252074d2/cryptography-50.0.2-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:d8947001be83df1394050758ce0e745dd74fb134eef0a4b5124208dfc3a68c37", size = 4354821, upload-time = "2026-09-30T14:44:26.263Z" }, + { url = "https://files.pythonhosted.org/packages/bd/e6/db28a28c7b6c676addce89136de3d8db49ea825a8c863472e36e42ead4ad/cryptography-50.0.2-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:4a20ce1e5cb4284a86692fdcba7cb8754185c6b2e5c56fcef3751cf451d3cdc2", size = 4716748, upload-time = "2026-09-30T14:44:28.447Z" }, + { url = "https://files.pythonhosted.org/packages/30/96/01546c7f69ea0e2ab790a2e4f0934a4052fb9b388147fbf83c2fd72f1e57/cryptography-50.0.2-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:84f964e537f916e2cc85199e5a88742e964939b575ac8598b3f9d6cc416cdaf1", size = 5285085, upload-time = "2026-09-30T14:44:30.704Z" }, + { url = "https://files.pythonhosted.org/packages/6c/01/03263395f74d50b071e9e66daace3f8bef80493e5d410726f2ba8554736b/cryptography-50.0.2-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:828d49b0ff5a0e3975865571c5d91dbbdd0d38d8289b249a163e9425413a5e05", size = 4727268, upload-time = "2026-09-30T14:44:32.92Z" }, + { url = "https://files.pythonhosted.org/packages/eb/94/2bfe8f29ec0cc9c0d99359c4161adf32858e4934b72c6d100d2ac0bbe962/cryptography-50.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:deb9fde5c60e437ee4821bc9bc39ff31b42135c27e1dc61ef0a629389c1de62e", size = 4849503, upload-time = "2026-09-30T14:44:34.969Z" }, + { url = "https://files.pythonhosted.org/packages/54/44/e80651ecbf0e42b62e2bb5f5768916e07eea72e1297338956a61df361f88/cryptography-50.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8c71ba2cd31fc93748c38e1b613200ff1c2665cbfd5341fe3a61cfde35a1430e", size = 5004057, upload-time = "2026-09-30T14:44:37.064Z" }, + { url = "https://files.pythonhosted.org/packages/f8/cc/1d33befb3cd7ea7e77d2d73f43f2066471da1b21f24a6156efcaabf6d2e8/cryptography-50.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:78198641e5be9521beea5aa782bb551a58068d10e6eb04c9c680c1b69f2e7d45", size = 3795868, upload-time = "2026-09-30T14:44:39.71Z" }, + { url = "https://files.pythonhosted.org/packages/2d/49/93f6a6e7a87c9aa68d44d3e1cdb5fe8f60c90d5d2f46acae9a56892816b8/cryptography-50.0.2-cp315-abi3.abi3t-macosx_11_0_arm64.whl", hash = "sha256:edc3342adf8f697fc5f59c887a304356f147b397809440ed64e2fa6af2f50f37", size = 4133708, upload-time = "2026-09-30T14:44:41.807Z" }, + { url = "https://files.pythonhosted.org/packages/8c/75/32ac2a56243d778805c16ca6a32b8f74fb757df7e28d7ecb560afafb59cf/cryptography-50.0.2-cp315-abi3.abi3t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d370b8d1dfcdf7130178137f6fbee6140774a1acc6cacefc4b42643ec11d0a3a", size = 4956267, upload-time = "2026-09-30T14:44:43.693Z" }, + { url = "https://files.pythonhosted.org/packages/aa/a4/2c8d734e43d97f0842ee9f1b7b4bfb3d0cf5e19edebf43c2afe6675c2320/cryptography-50.0.2-cp315-abi3.abi3t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f2f9bd7f90c64fe89253f0a2c05e3c4856072660429ce8831b4235bf29403a67", size = 4966465, upload-time = "2026-09-30T14:44:45.769Z" }, + { url = "https://files.pythonhosted.org/packages/c2/58/ee288c829a6f41f6235ae9dd33d82fd19b45442b65b4c8a3da36963d9f7a/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_28_aarch64.whl", hash = "sha256:e275096ea1e60cc595cda2836fd4a6c725d1125108b868be17f53684d164e2cc", size = 4959356, upload-time = "2026-09-30T14:44:48.211Z" }, + { url = "https://files.pythonhosted.org/packages/92/20/9ded6d51ddd9897f6b6e81fb9ebea7951d7cc5d6c890b0ed8abf77a51a80/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_28_ppc64le.whl", hash = "sha256:b13478603dcd0a2479ff8e87e2c19a7d525734686fe3c49542472293a204212d", size = 5548822, upload-time = "2026-09-30T14:44:50.86Z" }, + { url = "https://files.pythonhosted.org/packages/02/a8/8df951850d6b31d2a00218f19e2b3f999523437ed7a819df7fa427942fca/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_28_x86_64.whl", hash = "sha256:58a0c478eeca76fe5e07993c5a0703def34a6dc6a0cda4f5564639b33112ffe7", size = 5001199, upload-time = "2026-09-30T14:44:53.379Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f9/36b3022218ce75b7cdf068fb95f809f9bd0d820e4955ef43b90c255cc7ac/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_31_armv7l.whl", hash = "sha256:d38cdff612d06fa6a32840d5e1b1f7a27cee4a349aa9085d94a67789d6bfd408", size = 4629333, upload-time = "2026-09-30T14:44:55.635Z" }, + { url = "https://files.pythonhosted.org/packages/8c/72/20f99a219f6af47cdd1cbd978c243b92d71496e168a746138af44ded4f29/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_34_aarch64.whl", hash = "sha256:fdd28f912fccfec1846a94e2e1e8f9b0012f557f0c46fe4f3eb0d7a87afcf90b", size = 4958822, upload-time = "2026-09-30T14:44:59.639Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/196f112617fb08eb4d608a2a6c422373d46f9cc2857f38fc0667033c0899/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_34_ppc64le.whl", hash = "sha256:cbc8738fd8526d80f35cb3a40d41f41a2e7030bb3b18b09a6778ef63d291c2fd", size = 5506351, upload-time = "2026-09-30T14:45:02.267Z" }, + { url = "https://files.pythonhosted.org/packages/24/95/83378121ef3eaaaf71d4b781577ff794acb39b9e1b87a3f156898c8497ed/cryptography-50.0.2-cp315-abi3.abi3t-manylinux_2_34_x86_64.whl", hash = "sha256:e105ab60406787da31fccc883fc0f733af1efd78f0136a4599692c4083a73d0c", size = 5000859, upload-time = "2026-09-30T14:45:05.009Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore2" +version = "2.13.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "h11" }, + { name = "truststore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/f3/1db7aa2bc2524062192bb0e0323969492d1883152a232fe36eea65f4e35c/httpcore2-2.13.1.tar.gz", hash = "sha256:e0aa977abe17e69a3b820a24542a6fa88702676d83880b8d194dcd18408e5103", size = 68071, upload-time = "2026-09-23T07:47:22.372Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/ba/a4568248771ce81957bfb7cc600264a40fbcda092391ee1c415c50be4bea/httpcore2-2.13.1-py3-none-any.whl", hash = "sha256:e1e05d4f25f7d7d496bfb96748f6f4b67657b03da069b3a68c36069f3db73d0a", size = 83423, upload-time = "2026-09-23T07:47:19.365Z" }, +] + +[[package]] +name = "httpx2" +version = "2.13.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio", marker = "sys_platform != 'emscripten'" }, + { name = "httpcore2", marker = "sys_platform != 'emscripten'" }, + { name = "httpx2-jsfetch", marker = "sys_platform == 'emscripten'" }, + { name = "idna" }, + { name = "truststore", marker = "sys_platform != 'emscripten'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d5/44/474bef2a0e9d90f1715d32cb98b0738695ca17ba324095fb2497ed7fbd59/httpx2-2.13.1.tar.gz", hash = "sha256:e48744a19e3af5ee48313d0ce5fe941d5422fae5705ea922a4aabf94d7800dfa", size = 100405, upload-time = "2026-09-23T07:47:23.052Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/9c/6fe8931fd9f381042a9e4c7d5a7b4cbf7016b252bec0c99a49fce42c3326/httpx2-2.13.1-py3-none-any.whl", hash = "sha256:6dff50fabc270ee5fd25d845d0b078ed20564579744d6d962850975996d2f9a4", size = 95597, upload-time = "2026-09-23T07:47:20.995Z" }, +] + +[[package]] +name = "httpx2-jsfetch" +version = "1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/0e5636363151a2a1795e0a77617168b9ca438e1748ec05fc9b5687f93d64/httpx2_jsfetch-1.0.tar.gz", hash = "sha256:70a0e3eabfef7cce5ad9c629f7d01ca05e418f586646f4ddf14782e4c1454c60", size = 6872, upload-time = "2026-08-07T00:13:07.492Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/43/832f631d32e4f1211caa2ba368317739fe71f0b8530e4c9d15dc454bac2a/httpx2_jsfetch-1.0-py3-none-any.whl", hash = "sha256:cb916b707601e69a07721aabc8f3f6659be3a6893bc1ff5c6f9e02241df2da32", size = 6382, upload-time = "2026-08-07T00:13:06.567Z" }, +] + +[[package]] +name = "idna" +version = "3.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/08/8eea9d4b8302028f3abb2c0813953f7aec26d33b7a8960ed760e65ff29fa/idna-3.20.tar.gz", hash = "sha256:a7db850025b95ded1eae8a46181a1a6c56c92c96f0e2b005d9ff8dc0210cab44", size = 216463, upload-time = "2026-09-17T14:11:04.752Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/a2/bb081bab032533a855d44de1d56f8e8426114ff1ba5d1f07a438a0a654f8/idna-3.20-py3-none-any.whl", hash = "sha256:ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c", size = 69583, upload-time = "2026-09-17T14:11:03.168Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "mcp" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "httpx2" }, + { name = "jsonschema" }, + { name = "mcp-types" }, + { name = "opentelemetry-api" }, + { name = "pydantic" }, + { name = "pyjwt", extra = ["crypto"] }, + { name = "python-multipart" }, + { name = "pywin32", marker = "sys_platform == 'win32'" }, + { name = "sse-starlette" }, + { name = "starlette" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, + { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/31/ac54fb0fdd5b37de704486e288bba4fbbb463f24cfcfedbede407b854513/mcp-2.2.0.tar.gz", hash = "sha256:2dc37ecb1974becdcebdbf7561e7c15a07dbbf20ba21ba16c3593b3038b3afbd", size = 4084129, upload-time = "2026-09-07T16:06:23.439Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/ff/8e7eade68b8a28f7da0ed1085544341b51f9c935dbf6b95c76b7edfea6a0/mcp-2.2.0-py3-none-any.whl", hash = "sha256:bde982589473a060ae145e3406e9a5333fe538c97229ba841f5a7f92be004f81", size = 365656, upload-time = "2026-09-07T16:06:19.711Z" }, +] + +[[package]] +name = "mcp-types" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/91/762d7755d971aff8a28d75f7961656148edf27875c8026e6385aaab08ae7/mcp_types-2.2.0.tar.gz", hash = "sha256:d3ed53703ddd10d9c6399f29d322bb66f3f67ab41348ac8556ba23e07fedefad", size = 65892, upload-time = "2026-09-07T16:06:25.187Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/d7/6ffba5d8cd5dd9b8a19478875c50e04945314ba5074e84d749283f27f62d/mcp_types-2.2.0-py3-none-any.whl", hash = "sha256:ea476b73ee86709ab5abc9452385ed36cc05907e582355622e294595c9a04f13", size = 69106, upload-time = "2026-09-07T16:06:21.461Z" }, +] + +[[package]] +name = "opentelemetry-api" +version = "1.45.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/dc/e12c1fe1ed8a7b7149777127b1a0e12ce5bd5a81d97408bedc2128c260f5/opentelemetry_api-1.45.0.tar.gz", hash = "sha256:711ede81773c8025c2c03dac0450bc89f3d30aea6eabcc815c570d4e35a963f7", size = 72115, upload-time = "2026-09-25T12:32:28.399Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/b9/040d1a1c7836922828e6480cd2366bb8fe0ebf75b413d2bb51a9b0e7f78f/opentelemetry_api-1.45.0-py3-none-any.whl", hash = "sha256:80e068aba7cd56c8b58512d6a36f8d25cb1dfaa0c0a4cc1c938ccf9f362d9cb3", size = 60020, upload-time = "2026-09-25T12:32:03.192Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + +[[package]] +name = "pydantic" +version = "2.13.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/ef/fc4f868f4e2cee79f863883abffceff107875f569b848507319842d2a681/pydantic-2.13.5.tar.gz", hash = "sha256:51a9c5f7b2f8e636f04c6cada605d9b6a3bf1348fdf945a3d8869b19bba0ee08", size = 845750, upload-time = "2026-08-28T14:04:00.916Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/47/c95ffc2009878c7aac0c5e08528022dcb885933252a88b5f170058014464/pydantic-2.13.5-py3-none-any.whl", hash = "sha256:346a034f080da3755d8e9cb5e00e8b07de1d39e4f6e2c87d8ab7cafa0b269a73", size = 472589, upload-time = "2026-08-28T14:03:59.136Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/f9/8a06bea35ef8daf588f707784c973a7046e0034c8d8cfb08828eeffb8b75/pydantic_core-2.46.5.tar.gz", hash = "sha256:10416c15b8839ecc4ef4d0885da76da6fd0f67333a0eb8aff6d93c4b8f2910fc", size = 472262, upload-time = "2026-08-28T10:01:31.677Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f5/37/5abe39a8372a61d3dc3c1338fc504281c01b32fdb3169cd7187153b56d3e/pydantic_core-2.46.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:b7ca9034437b6022f941f4857459562ee00a560b97e7cce8a0ec5a74fc6766e0", size = 2075885, upload-time = "2026-08-28T09:58:47.856Z" }, + { url = "https://files.pythonhosted.org/packages/21/43/6323b1f8b217780454c61304bcd2b38ae4762f50754414124603ccc90bb2/pydantic_core-2.46.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f332f0e72a5a0400141f830744e141bf9f97917878dbe968669e8a7fefea78ff", size = 1922768, upload-time = "2026-08-28T09:58:49.58Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a3/c05ca796e1197618a774b01e596aeedfefc2f7d8c01ae3054e910b120e8a/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:193375f3548919d3f0b60936ca113ada3e38f264f91b9b8e0508efaad57be931", size = 1951241, upload-time = "2026-08-28T09:58:51.511Z" }, + { url = "https://files.pythonhosted.org/packages/68/32/33bc39ac705c52cffc908e8389f9754fdb208aea5c69cceddf4eb3ce99af/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79bdfa52f843137045b2d081cc05c120ba6665d29b7559c2c47690906f39279f", size = 2031975, upload-time = "2026-08-28T09:58:53.166Z" }, + { url = "https://files.pythonhosted.org/packages/b0/70/2333e885c0f6a67bc105c5916965dac9b57f2718ee20d81d1a06a4ebdc13/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24922243639cbdac66c75fcb6fd6495a9cb52b213d62f9a0d16f0310b1ff8038", size = 2208542, upload-time = "2026-08-28T09:58:55.017Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ea/296debfb4264207bbda5936133892e027c0a58875ad53ebd512fba8ec3a2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c76fe65e607be28c7fd4d56fc3c42b1583aa058ce3408b7ad0fd540171d31f9f", size = 2264692, upload-time = "2026-08-28T09:58:56.767Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f2/9e4de77a6271e07a76d2d58b11c091a979c191ed2939bf80067568b369d2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f7b393a8b3da82f5c1fc0751e6d01ac6c55b93c18226a60bdfba4a724efafd1", size = 2066633, upload-time = "2026-08-28T09:58:58.531Z" }, + { url = "https://files.pythonhosted.org/packages/8d/db/f9e9d0c97445987b2084823d5c240de88087338f04fc2cfaa2df186b8049/pydantic_core-2.46.5-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:7ac031912d54f3d83ef3b3eb98dfabc1608802e2202263d25957eeed40b94761", size = 2105235, upload-time = "2026-08-28T09:59:00.421Z" }, + { url = "https://files.pythonhosted.org/packages/07/c5/79169b047b3b2c3e99e04bc76372af9637e0bf6db638274fa927df96369e/pydantic_core-2.46.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:837b396ca3d7b74091ca623f6cbd8351bd42d670a79c2683e79fb089f06a2de5", size = 2157367, upload-time = "2026-08-28T09:59:02.442Z" }, + { url = "https://files.pythonhosted.org/packages/26/b5/ba6057afb7c291bd449f51b867f95aef2072941c4ce4e5c31d6ffd132d3b/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:5ee239d575f80b08eca11f6e20f90c4c695de7825c67eefe6091fbf20dda648e", size = 2158420, upload-time = "2026-08-28T09:59:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/6e/28/2057abecaafdc22912afa819603a51f0a62d40643b7c4871c51721fea9be/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:e80675d75ae2cd14372cb65cad5400d9347a3d3f6c13000183f22dfd027283ed", size = 2309588, upload-time = "2026-08-28T09:59:06.048Z" }, + { url = "https://files.pythonhosted.org/packages/71/9d/881156dc404e27479c4246128d73538464cab4a239bec61995e227644c30/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c4b71f10dd532fb7a5cbc8f58707779e64f03a258c2bf8bfbaecfcd9970b519", size = 2341866, upload-time = "2026-08-28T09:59:08.539Z" }, + { url = "https://files.pythonhosted.org/packages/5a/38/d66f443a259f84d13babdceae568e572b0ed26da17ca5d0a649ebb110a67/pydantic_core-2.46.5-cp313-cp313-win32.whl", hash = "sha256:97bf8de4d541598c94a59344eeb988a94c08ff76b5723c41f6567ec18c7892ea", size = 1938580, upload-time = "2026-08-28T09:59:10.402Z" }, + { url = "https://files.pythonhosted.org/packages/2c/1e/1d5371213f4cc9a7ed70c0bfcc7911de22311ee99a662a56077d7292d2ac/pydantic_core-2.46.5-cp313-cp313-win_amd64.whl", hash = "sha256:15f4a94963c95accac15b7b657bb177d3ad82bb90b0d0526d9a9b85079925db5", size = 2041980, upload-time = "2026-08-28T09:59:12.396Z" }, + { url = "https://files.pythonhosted.org/packages/5a/48/4222d90b1c67568bace4dec6dca6271449c66de3595d72b6d098f5fde597/pydantic_core-2.46.5-cp313-cp313-win_arm64.whl", hash = "sha256:d22a945598fb91236b4dd793a6e42e4f3dd7740bb5aace5ebd7d4c08d13bb575", size = 1997213, upload-time = "2026-08-28T09:59:14.245Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8a/14596f2a8367da50cf7cbac48169ee5d9c8e11d486a3b527082384630c72/pydantic_core-2.46.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c1c43ad4339643d70ebb8124e1305a7dab423001eff58bb41a0f731adbc98355", size = 2074081, upload-time = "2026-08-28T09:59:16.141Z" }, + { url = "https://files.pythonhosted.org/packages/ae/d5/d8a4eb6d6c7f66b91dd37c576d76e9e60fba900caf5372c17bcf949febc2/pydantic_core-2.46.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1a353f84de772f423b5ffb11d7ae352fbbef0f446f3c0b0af0f8236d7233606e", size = 1920497, upload-time = "2026-08-28T09:59:18.065Z" }, + { url = "https://files.pythonhosted.org/packages/8e/26/092079428f86e927e030b2c0ced87df69dbb1c875cdeaa67bf42ea2be746/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5086029a57366b8cf81b130a43908738095c270c21a8d7f0e8bdfdb89718e2f3", size = 1952130, upload-time = "2026-08-28T09:59:20.476Z" }, + { url = "https://files.pythonhosted.org/packages/08/c3/8ec0e290a9ebaebd64047bf5fda94be835c6b1551b02437e4b76778fbcd7/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46c25dda9d092a06c08db76ffe0a197107904d0dfac653f7d5306bbcd6d6119c", size = 2026371, upload-time = "2026-08-28T09:59:22.227Z" }, + { url = "https://files.pythonhosted.org/packages/01/72/4fd20ad520fb8da0157f95b27a7eb05a72790ef08138e7701ac972c342ea/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37ea7b83c935e5b0d68c9449b82651accf78a10828b2c02b2f2d9e9496446c21", size = 2202822, upload-time = "2026-08-28T09:59:24.277Z" }, + { url = "https://files.pythonhosted.org/packages/31/b0/d16e0771206b29314f0d52198b720be21e8a99ab2bf11e3bc0d7c9cebdff/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e64e88d5585bea9ce95861079de72006c7fa6d3df4e3a3b65ba31eb979c15c9f", size = 2262756, upload-time = "2026-08-28T09:59:26.608Z" }, + { url = "https://files.pythonhosted.org/packages/2c/9b/59634b7ac631c63b2a37760eb6943af3e29573d6b59a4abc5e7f019d4cee/pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d510bac3ee52247af28ed4bb18a1e799f040ac60fd2bf5ccd4c92f1fbe786f", size = 2068352, upload-time = "2026-08-28T09:59:29.044Z" }, + { url = "https://files.pythonhosted.org/packages/08/7c/570abb1ad2155348dc754ea91be22e5aaa18eb6d69a6068f7c6f2679a6ed/pydantic_core-2.46.5-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:a2a5e1d0ff29adddc9f6d6821a66302e4493f8ca898b715b6b1182c2c201ea0a", size = 2104777, upload-time = "2026-08-28T09:59:30.95Z" }, + { url = "https://files.pythonhosted.org/packages/8e/25/5bf74adc65a1ac5b7be3f6cb0bcb5433615c1598a801c19d830d84c98ded/pydantic_core-2.46.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:03b9666e41e35d8909852ba191a0607520f81b74eaf12ccf8737005dbb313821", size = 2156312, upload-time = "2026-08-28T09:59:32.604Z" }, + { url = "https://files.pythonhosted.org/packages/90/6a/2ef38830675e050121040618135564ed56b860b45433b02d9b4ebece46f3/pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:a91c17edf6eea2402cb5457b4c89e99bc5ed1004aa34c4adf1d4258c1a5c22c2", size = 2150067, upload-time = "2026-08-28T09:59:34.453Z" }, + { url = "https://files.pythonhosted.org/packages/90/ef/a7dbb03a14a64c2a4621f989c615ed9a892535a6cad938fc27079f919d80/pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b49924c73a235e969511bf2aabdff3beebf9820931f646c80274d5d780010c47", size = 2304516, upload-time = "2026-08-28T09:59:36.194Z" }, + { url = "https://files.pythonhosted.org/packages/68/f8/6bb4c4b80e8a6fde1904c64a51c62a1d04fcdfa3ea521a66b2ddefa1d885/pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:2cbd9a5eff05e51c447c34dfa4632145b26b09120cf04bd0c871e44c1a5e1c9a", size = 2335223, upload-time = "2026-08-28T09:59:37.931Z" }, + { url = "https://files.pythonhosted.org/packages/2a/80/f46b8c681195190b2c1f1c7c0a81abce60663e987613e09ef64d433dd96b/pydantic_core-2.46.5-cp314-cp314-win32.whl", hash = "sha256:2d5d76654becf5efd62c9e51c3756c67b49498b0c9a40884934c40807adbd074", size = 1934827, upload-time = "2026-08-28T09:59:39.836Z" }, + { url = "https://files.pythonhosted.org/packages/f7/3c/60674207246bc0a4009d2391b7c7251c7159f279c8d2ab8aae8ef46f3dee/pydantic_core-2.46.5-cp314-cp314-win_amd64.whl", hash = "sha256:fa10ef4112775900e7a0661068635eb67b2ab824fbde764de6e0e21982a93db0", size = 2042648, upload-time = "2026-08-28T09:59:41.792Z" }, + { url = "https://files.pythonhosted.org/packages/69/0c/117c562c7c1babdf44576b72a5e496906506c93690387ecfbca7c729ae2e/pydantic_core-2.46.5-cp314-cp314-win_arm64.whl", hash = "sha256:045ab3b6d308439e32b81cc173bba5b9018bc6ed896afd0c65b3b009b1699af5", size = 1989652, upload-time = "2026-08-28T09:59:43.702Z" }, + { url = "https://files.pythonhosted.org/packages/e8/66/9336ae58f9eb68c41d121894e52c4c89eccb07eb8f602a04ee9c3f37736a/pydantic_core-2.46.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8816f3d218beb4b787de5c9759c259b8fa61f9dec42dc7811f320a33771778b7", size = 2065829, upload-time = "2026-08-28T09:59:45.364Z" }, + { url = "https://files.pythonhosted.org/packages/c5/02/bc19b47a96c2d3109760711acf22369e56bd7e405ca52f7ade164d2ead57/pydantic_core-2.46.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:bce57638e08ac148e5778cce7feb968307a727d66f8e2274a543d0cf0c9ad6a3", size = 1905716, upload-time = "2026-08-28T09:59:47.18Z" }, + { url = "https://files.pythonhosted.org/packages/52/a4/70b47c0509923dd98ccfed04fb3e32ea3849c82a0ff2205bb41009b43c00/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:976e1128455aa595ea04c79ccfedff1aaeab96ee013fcc916bed120c4f0ad94f", size = 1934216, upload-time = "2026-08-28T09:59:49.241Z" }, + { url = "https://files.pythonhosted.org/packages/52/ab/aa03b65f7bb198585edf806b906c3223ecf1795543e39e23aec4cce27ad2/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b891faeedeafba41b2983e5001a81b6a915b69544c7e7570d1989ce1c36ac7", size = 2010635, upload-time = "2026-08-28T09:59:51.692Z" }, + { url = "https://files.pythonhosted.org/packages/3c/8b/0da06343f30b84ec549aafd309c6456223d5dc8bd36af504c573faad561d/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f194189415698233dd1114a093a9b56e61e2c57e11b469be3b0506f46f0771c", size = 2209369, upload-time = "2026-08-28T09:59:53.582Z" }, + { url = "https://files.pythonhosted.org/packages/d6/5b/844c4defaa34a3df66eb9257087d121d70c201298b96abdf9f492fc2f1bf/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82a36973cf8a2ef5406f4fe2edbf8ed0c99629535d959e0b100c76a32535a111", size = 2253238, upload-time = "2026-08-28T09:59:55.484Z" }, + { url = "https://files.pythonhosted.org/packages/f4/64/a4e536cb16d7f61a7fd3120b46c577fc7fa7325992f69c4f52bc786d77d8/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdbb78909f52b981d3b2d56b97328d71eb0b974c36bd77c920123a7ebb192829", size = 2065740, upload-time = "2026-08-28T09:59:58.038Z" }, + { url = "https://files.pythonhosted.org/packages/5f/75/aaa38c6bc2d085f6605b34eabdc6a8a4e0b2e61fc9c8e6e52b28e97b3125/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:52e24eacdb536cade636aa90fb851835222becff8484b7001fdc78cb0290f2aa", size = 2087425, upload-time = "2026-08-28T09:59:59.898Z" }, + { url = "https://files.pythonhosted.org/packages/55/ae/fcab4cfc39aba3689e1d20c8b5250ad280957022c09af2ed9cd585602a5e/pydantic_core-2.46.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:37ae34309d7bd8c0d61ab839668058f2a7962ea1fc51d105d2db228fe0618034", size = 2139306, upload-time = "2026-08-28T10:00:03.057Z" }, + { url = "https://files.pythonhosted.org/packages/2d/f4/f1d03a4bc9d9acbc62f4d742b8a319af52f71885079868b2ff8e48a651ee/pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:0cdbada856a1c69a7624a64d3d9aefe79300bd6ef827b43a4f265010b9b55184", size = 2144589, upload-time = "2026-08-28T10:00:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/83/f3/7a53bb1356de514a4cd295f25b6ac39237895620c0462d2592b76c16e114/pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:545f26c504b27c3758439a5e6d9349931f0a04f855668d5fe323c89e82300a38", size = 2288882, upload-time = "2026-08-28T10:00:07.931Z" }, + { url = "https://files.pythonhosted.org/packages/cd/94/5a81583660c175c59d49ffb09f4b3a44debeaf86a19fca664ae1cdd9ee32/pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:ff218293c9c806138dca139765e3b067621be52bcd93cdc14c7711be7ddc90a9", size = 2335210, upload-time = "2026-08-28T10:00:10.177Z" }, + { url = "https://files.pythonhosted.org/packages/5a/9f/5d685c2693b972d1a59c998586e8823712b66603aeff47ee60a4bdaafd37/pydantic_core-2.46.5-cp314-cp314t-win32.whl", hash = "sha256:97cf3eb53a8cccacf9d46686a0926186c9bfb5574f2ed66d3639d5fe117cd3a9", size = 1921180, upload-time = "2026-08-28T10:00:12.35Z" }, + { url = "https://files.pythonhosted.org/packages/70/12/5c94ee16d65a37a15f9e869f5e6256df111154491173801a4c5e800ab548/pydantic_core-2.46.5-cp314-cp314t-win_amd64.whl", hash = "sha256:d2f9fc07a8042a8f95925b35c4f04f469707c981fc33245b6ca187cf5d2dd290", size = 2020515, upload-time = "2026-08-28T10:00:14.774Z" }, + { url = "https://files.pythonhosted.org/packages/63/19/67830dda664e6bdf9285ee2e40f355d0d7d6b92aa0c42e8d217bb8d33d36/pydantic_core-2.46.5-cp314-cp314t-win_arm64.whl", hash = "sha256:acf8a67ba51f4ca9ddbd0e6b3000a65ac51ab734661778b3e7ba64d99a710f2f", size = 1989276, upload-time = "2026-08-28T10:00:16.984Z" }, +] + +[[package]] +name = "pyjwt" +version = "2.15.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/ea/5194e52748b0da83d71e082d75496eaec6e58f419f5e184786ded517e6a9/pyjwt-2.15.1.tar.gz", hash = "sha256:4f259e80cdfb6b3fc18a7de51fd1ef9ec79652f25019bae68975ca2468a34df8", size = 121252, upload-time = "2026-09-28T18:40:42.598Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/ca/44de4e75f8aadc457f0634be3b542815078ded46dca30efb960edeecad6e/pyjwt-2.15.1-py3-none-any.whl", hash = "sha256:42d59d631f7768a1028a64c7ff581a9bf7519804daf91fc5b6c56e30eec5e193", size = 33860, upload-time = "2026-09-28T18:40:41.429Z" }, +] + +[package.optional-dependencies] +crypto = [ + { name = "cryptography" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.32" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/42/55c32bb9b12693c092ad250a0e82edb5b31ddeda6eb772de5f308b3804ad/python_multipart-0.0.32.tar.gz", hash = "sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e", size = 46881, upload-time = "2026-06-04T16:18:58.647Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/04/e8135ebd1ad02c56ec633277529b2602ff99ff634be76cdba5744cf554fd/python_multipart-0.0.32-py3-none-any.whl", hash = "sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23", size = 30042, upload-time = "2026-06-04T16:18:57.319Z" }, +] + +[[package]] +name = "pywin32" +version = "312" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/41/12fbfd7f36ed2146d8bc9de96c2741296bf0d490b98508496cff322e274c/pywin32-312-cp313-cp313-win32.whl", hash = "sha256:7a27df850933d16a8eabfbaeb73d52b273e2da667f80d70b01a89d1f6828d02c", size = 6370184, upload-time = "2026-06-04T07:49:36.253Z" }, + { url = "https://files.pythonhosted.org/packages/ba/db/36a78e3403099d31d9746d13fdcde5accc43c1155f375a34d15983a479a7/pywin32-312-cp313-cp313-win_amd64.whl", hash = "sha256:c53e878d15a1c44788082bfe712a905433473aa38f86375b7cf8b45e3acbaaf9", size = 6914298, upload-time = "2026-06-04T07:49:38.876Z" }, + { url = "https://files.pythonhosted.org/packages/84/37/c1697194092b76de9ed47ca124323f02c57ffc8a45c06f88a3d5acaf01eb/pywin32-312-cp313-cp313-win_arm64.whl", hash = "sha256:59aba5d5940842075343a5ddc6b11f1cdf0d1567fe745290359dfbcc7c2eb831", size = 6727640, upload-time = "2026-06-04T07:49:41.083Z" }, + { url = "https://files.pythonhosted.org/packages/fc/2b/1f3cded5822fd49c02f40544cbb5f58c7cfd6b1694869fd476cb6170ee97/pywin32-312-cp314-cp314-win32.whl", hash = "sha256:a77a90fbb6881238d2ca9c6fd797b25817f3768fe78d214a90137ff055a75f5b", size = 6468928, upload-time = "2026-06-04T07:49:43.188Z" }, + { url = "https://files.pythonhosted.org/packages/21/82/3bf86d2e2808902013132e1ce905a7da0da53790f3836c64bf44d55e24f3/pywin32-312-cp314-cp314-win_amd64.whl", hash = "sha256:a4dd3a848290ef724347b19f301045831d8e802fa4464f491b98b1e0a081432e", size = 7024157, upload-time = "2026-06-04T07:49:45.34Z" }, + { url = "https://files.pythonhosted.org/packages/a4/0e/73f6d6800b4f27655abd9e9f6aaeaefcddb2b946e4674efa2bab184a7f7b/pywin32-312-cp314-cp314-win_arm64.whl", hash = "sha256:9fce94568364e0155e6dfb781ac5d95903be8baf28670632beab1b523f300daa", size = 6839598, upload-time = "2026-06-04T07:49:47.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/61/caa39686032d2ebdd04ff0ab5cbe163126c0066d98e00c9018646e42393b/pywin32-312-cp315-cp315-win32.whl", hash = "sha256:5c1fbe4a937a73ae9297384a3da38518cbc694c68ad8a809b2e19acd350f03ed", size = 6471159, upload-time = "2026-06-04T07:49:50.035Z" }, + { url = "https://files.pythonhosted.org/packages/0f/cd/7e1de64a4a6f69c04214169657ccab0d93a670ea50e35eb8f489d7378249/pywin32-312-cp315-cp315-win_amd64.whl", hash = "sha256:c2f03a0f73f804a13c2735b99392b0cd426bb4f2c4d0178e5ac966a0f21618d5", size = 7025293, upload-time = "2026-06-04T07:49:54.857Z" }, + { url = "https://files.pythonhosted.org/packages/23/ed/4532e9388e65fa16b46776ef47ad631a64eda1631884488af707666350ed/pywin32-312-cp315-cp315-win_arm64.whl", hash = "sha256:a8597d28f267b39074aef51fa593530082b39cbe5a074226096857b1fed2dfb9", size = 6840337, upload-time = "2026-06-04T07:49:57.531Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "rpds-py" +version = "2026.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/9e/b818ee580026ec578138e961027a68820c40afeb1ec8f6819b54fb99e196/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223", size = 343012, upload-time = "2026-06-30T07:15:36.005Z" }, + { url = "https://files.pythonhosted.org/packages/f3/6b/686d9dc4359a8f163cfbbf89ee0b4e586431de22fe8248edb63a8cf50d49/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f", size = 338203, upload-time = "2026-06-30T07:15:37.462Z" }, + { url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" }, + { url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" }, + { url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" }, + { url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" }, + { url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" }, + { url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" }, + { url = "https://files.pythonhosted.org/packages/85/ed/adab103321c0a6565d5ae1c2998349bc3ee175b82ccc5ae8fc04cc413075/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0", size = 201710, upload-time = "2026-06-30T07:15:53.894Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/a03b09668e74e5dabbf2e211f6468e1820c0552f7b0500082da31841bf7b/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80", size = 219454, upload-time = "2026-06-30T07:15:55.25Z" }, + { url = "https://files.pythonhosted.org/packages/27/17/b8642c12930b71bc2b25831f6708ccf0f75abcd11883932ec9ce54ba3a78/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb", size = 215063, upload-time = "2026-06-30T07:15:56.573Z" }, + { url = "https://files.pythonhosted.org/packages/b6/36/7fbe9dcdaf857fb3f63c2a2284b62492d95f5e8334e947e5fb6e7f68c9be/rpds_py-2026.6.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:931908d9fc855d8f74783377822be318edb6dcb19e47169dc038f9a1bf60b06e", size = 344510, upload-time = "2026-06-30T07:15:57.921Z" }, + { url = "https://files.pythonhosted.org/packages/ba/54/f785cc3d3f60839ca57a5af4927a9f347b07b2799c373fc20f7949f87c7e/rpds_py-2026.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7469697dce35be237db177d42e2a2ee26e6dcc5fc052078a6fefabd288c6edd", size = 339495, upload-time = "2026-06-30T07:15:59.238Z" }, + { url = "https://files.pythonhosted.org/packages/63/ef/d4cdaf309e6b095b43597103cf8c0b951d6cca2acce68c474f75ec12e0c7/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d", size = 369454, upload-time = "2026-06-30T07:16:01.021Z" }, + { url = "https://files.pythonhosted.org/packages/96/4a/9559a68b7ee15db09d7981212e8c2e219d2a1d6d4faa0391d813c3496a36/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda", size = 374583, upload-time = "2026-06-30T07:16:02.287Z" }, + { url = "https://files.pythonhosted.org/packages/ef/75/8964aa7d2c6e8ac43eba8eb6e6b0fdda1f46d39f2fc3e6aa9f2cb17f485d/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8", size = 492919, upload-time = "2026-06-30T07:16:03.723Z" }, + { url = "https://files.pythonhosted.org/packages/8f/97/6908094ac804115e65aedfd90f1b5fee4eebebd3f6c4cfc5419939267565/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53", size = 383725, upload-time = "2026-06-30T07:16:05.305Z" }, + { url = "https://files.pythonhosted.org/packages/d1/9c/0d1fdc2e7aba23e290d603bc494e97bd205bae262ce33c6b32a69768ed5e/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504", size = 367255, upload-time = "2026-06-30T07:16:07.086Z" }, + { url = "https://files.pythonhosted.org/packages/c4/fe/f0209ca4a9ed074bc8acb44dfd0e81c3122e94c9689f5645b7973a866719/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc", size = 379060, upload-time = "2026-06-30T07:16:08.525Z" }, + { url = "https://files.pythonhosted.org/packages/c6/8d/f1cc54c616b9d8897de8738aac148d20afca93f68187475fe194d09a71b9/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77", size = 395960, upload-time = "2026-06-30T07:16:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/fb/04/aafff00f73aeca2945f734f1d483c64ab8f472d0864ab02377fd8e89c3b2/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698", size = 545356, upload-time = "2026-06-30T07:16:11.816Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cc/e229663b9e4ddac5a4acbe9085dd80a71af2a5d356b8b39d6bff233f24b0/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd", size = 612319, upload-time = "2026-06-30T07:16:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7a/8a0e6d3e6cd066af108b71b43122c3fe158dd9eb86acac626593a2582eb1/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d", size = 573508, upload-time = "2026-06-30T07:16:15.23Z" }, + { url = "https://files.pythonhosted.org/packages/87/03/2a69ab618a789cf6cf85c86bb844c62d090e700ab1a2aa676b3741b6c516/rpds_py-2026.6.3-cp314-cp314-win32.whl", hash = "sha256:882076c00c0a608b131187055ddc5ae29f2e7eaf870d6168980420d58528a5c8", size = 202504, upload-time = "2026-06-30T07:16:16.893Z" }, + { url = "https://files.pythonhosted.org/packages/85/62/a3892ba945f4e24c78f352e5de3c7620d8479f73f211406a97263d13c7d2/rpds_py-2026.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:0be972be84cfcaf46c8c6edf690ca0f154ac17babf1f6a955a51579b34ad2dc5", size = 220380, upload-time = "2026-06-30T07:16:18.108Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e7/c2bd44dc831931815ad11ebb5f430b5a0a4d3caa9de837107876c30c3432/rpds_py-2026.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:2a9c6f195058cb45335e8cc3802745c603d716eb96bc9625950c1aac71c0c703", size = 215976, upload-time = "2026-06-30T07:16:19.654Z" }, + { url = "https://files.pythonhosted.org/packages/79/9c/fff7b74bce9a091ec9a012a03f9ff5f69364eaf9451060dfc4486da2ffdd/rpds_py-2026.6.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f90938e92afda60266da758ee7d363447f7f0138c9559f9e1811629580582d90", size = 346840, upload-time = "2026-06-30T07:16:21.268Z" }, + { url = "https://files.pythonhosted.org/packages/e9/44/77bcb1168b33704908295533d27f10eb811e9e3e193e8993dc99572211d3/rpds_py-2026.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec829541c45bca16e61c7ae50c20501f213605beb75d1aba91a6ee37fbbb56a4", size = 340282, upload-time = "2026-06-30T07:16:22.875Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/7a9081c7c9e645b39efe19e4ffbeccd80add246327cd9b888aecffd72317/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9", size = 370403, upload-time = "2026-06-30T07:16:24.415Z" }, + { url = "https://files.pythonhosted.org/packages/f7/69/af47021eb7dad6ff3396cb001c08f0f3c4d06c20253f75be6421a59fe6b7/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f", size = 376055, upload-time = "2026-06-30T07:16:26.111Z" }, + { url = "https://files.pythonhosted.org/packages/81/fc/a3bcf517084396a6dd258c592567a3c011ba4557f2fde23dceaf26e74f2e/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41", size = 494419, upload-time = "2026-06-30T07:16:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/c9/eb/13d529d1788135425c7bf207f8463458ca5d92e43f3f701365b83e9dffc1/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945", size = 384848, upload-time = "2026-06-30T07:16:29.183Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f4/b7ac49f30013aba8f7b9566b1dd07e81de95e708c1374b7bacc5b9bc5c9c/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f", size = 371369, upload-time = "2026-06-30T07:16:30.912Z" }, + { url = "https://files.pythonhosted.org/packages/31/86/6260bafa622f788b07ddec0e52d810305c8b9b0b8c27f58a2ab04bf62b4f/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1", size = 379673, upload-time = "2026-06-30T07:16:32.486Z" }, + { url = "https://files.pythonhosted.org/packages/19/c3/03f1ee79a047b48daeca157c89a18509cde22b6b951d642b9b0af1be660a/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e", size = 397500, upload-time = "2026-06-30T07:16:34.471Z" }, + { url = "https://files.pythonhosted.org/packages/f0/95/8ed0cd8c377dca12aea498f119fe639fc474d1461545c39d2b5872eb1c0f/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538", size = 545978, upload-time = "2026-06-30T07:16:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f2/0eb57f0eaa83f8fc152a7e03de968ab77e1f00732bebc892b190c6eebde7/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db", size = 613350, upload-time = "2026-06-30T07:16:38.213Z" }, + { url = "https://files.pythonhosted.org/packages/5b/de/e0674bdbc3ef7634989b3f854c3f34bc1f587d36e5bfdc5c378d57034619/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2", size = 576486, upload-time = "2026-06-30T07:16:39.797Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f6/21101359743cd136ada781e8210a85769578422ba460672eea0e29739200/rpds_py-2026.6.3-cp314-cp314t-win32.whl", hash = "sha256:6de4744d05bd1aa1be4ed7ea1189e3979196808008113bbbf899a460966b925e", size = 201068, upload-time = "2026-06-30T07:16:41.316Z" }, + { url = "https://files.pythonhosted.org/packages/a6/b2/9574d4d44f7760c2aa32d92a0a4f41698e33f5b204a0bf5c9758f52c79d5/rpds_py-2026.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:c7b9a2f8f4d8e90af72571d3d495deebdd7e3c75451f5b41719aee166e940fc2", size = 220600, upload-time = "2026-06-30T07:16:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/08/ae/f23a2697e6ee6340a578b0f136be6483657bef0c6f9497b752bb5c0964bb/rpds_py-2026.6.3-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:e059c5dde6452b44424bd1834557556c226b57781dee1227af23518459722b13", size = 344726, upload-time = "2026-06-30T07:16:44.5Z" }, + { url = "https://files.pythonhosted.org/packages/c3/63/e7b3a1a5358dd32c930a1062d8e15b67fd6e8922e81df9e91706d66ee5c8/rpds_py-2026.6.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2f7c26fbc5acd2522b95d4177fe4710ffd8e9b20529e703ffbf8db4d93903f05", size = 339587, upload-time = "2026-06-30T07:16:46.255Z" }, + { url = "https://files.pythonhosted.org/packages/ec/64/10a85681916ca55fffb91b0a211f84e34297c109243484dd6394660a8a7c/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba", size = 369585, upload-time = "2026-06-30T07:16:48.101Z" }, + { url = "https://files.pythonhosted.org/packages/76/c2/baf95c7c38823e12ba34407c5f5767a89e5cf2233895e56f608167ae9493/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617", size = 375479, upload-time = "2026-06-30T07:16:49.93Z" }, + { url = "https://files.pythonhosted.org/packages/6a/94/0aad06c72d65101e11d33528d438cda99a39ce0da99466e156158f2541d3/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9", size = 492418, upload-time = "2026-06-30T07:16:51.641Z" }, + { url = "https://files.pythonhosted.org/packages/b5/17/de3f5a479a1f056535d7489819639d8cd591ea6281d700390b43b1abd745/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb", size = 384123, upload-time = "2026-06-30T07:16:53.622Z" }, + { url = "https://files.pythonhosted.org/packages/46/7d/bf09bd1b145bb2671c03e1e6d1ab8651858d90d8c7dfeadd85a37a934fd8/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885", size = 367351, upload-time = "2026-06-30T07:16:55.241Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ea/1bb734f314b8be319149ddee80b18bd41372bdcfbdf88d28131c0cd37719/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a", size = 378827, upload-time = "2026-06-30T07:16:56.841Z" }, + { url = "https://files.pythonhosted.org/packages/4b/93/d9611e5b25e26df9a3649813ed66193ace9347a7c7fc4ab7cf70e94851c0/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868", size = 395966, upload-time = "2026-06-30T07:16:58.557Z" }, + { url = "https://files.pythonhosted.org/packages/c3/cb/99d77e16e5534ae1d90629bbe419ba6ee170833a6a85e3aa1cc41726fbbc/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187", size = 545680, upload-time = "2026-06-30T07:17:00.164Z" }, + { url = "https://files.pythonhosted.org/packages/59/15/11a29755f790cef7a2f755e8e14f4f0c33f39489e1893a632a2eee59672b/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107", size = 611853, upload-time = "2026-06-30T07:17:01.962Z" }, + { url = "https://files.pythonhosted.org/packages/68/86/0c27547e21644da938fb530f7e1a8148dd24d02db07e7a5f2567a17ce710/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba", size = 573715, upload-time = "2026-06-30T07:17:03.693Z" }, + { url = "https://files.pythonhosted.org/packages/29/71/4d8fcf700931815594bce892255bbd973b94efaf0fc1932b0590df18d886/rpds_py-2026.6.3-cp315-cp315-win32.whl", hash = "sha256:d483fe17f01ad64b7bf7cc38fcefff1ca9fb83f8c2b2542b68f97ffe0611b369", size = 202864, upload-time = "2026-06-30T07:17:05.746Z" }, + { url = "https://files.pythonhosted.org/packages/eb/62/b577562de0edbb55b2be85ce5fd09c33e386b9b13eee09833af4240fd5c4/rpds_py-2026.6.3-cp315-cp315-win_amd64.whl", hash = "sha256:67e3a721ffc5d8d2210d3671872298c4a84e4b8035cfe42ffd7cde35d772b146", size = 220430, upload-time = "2026-06-30T07:17:07.471Z" }, + { url = "https://files.pythonhosted.org/packages/c8/95/d6d0b2509825141eef60669a5739eec88dbc6a48053d6c92993a5704defe/rpds_py-2026.6.3-cp315-cp315-win_arm64.whl", hash = "sha256:6e84adbcf4bf841aed8116a8264b9f50b4cb3e7bd89b516122e616ac56ca269e", size = 215877, upload-time = "2026-06-30T07:17:09.008Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bf/f3ea278f0afd615c1d0f19cb69043a41526e2bb600c2b536eb192218eb27/rpds_py-2026.6.3-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ae6dd8f10bd17aad820876d24caec9efdafd80a318d16c0a48edb5e136902c6b", size = 346933, upload-time = "2026-06-30T07:17:10.762Z" }, + { url = "https://files.pythonhosted.org/packages/9d/29/9907bdf1c5346763cf10b7f6852aad86652168c259def904cbe0082c5864/rpds_py-2026.6.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bdbd97738551fca3917c1bd7188bec1920bb520104f28e7e1007f9ceb17b7690", size = 340274, upload-time = "2026-06-30T07:17:12.266Z" }, + { url = "https://files.pythonhosted.org/packages/6f/2c/8e03767b5778ef25cebf74a7a91a2c3806f8eced4c92cb7406bbe060756d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342", size = 370763, upload-time = "2026-06-30T07:17:14.107Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e1/df2a7e1ba2efd796af26194250b8d42c821b46592311595162af9ef0528d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6", size = 376467, upload-time = "2026-06-30T07:17:15.76Z" }, + { url = "https://files.pythonhosted.org/packages/6b/de/8a0814d1946af29cb068fb259aa8622f856df1d0bab58429448726b537f5/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140", size = 496689, upload-time = "2026-06-30T07:17:17.308Z" }, + { url = "https://files.pythonhosted.org/packages/df/f3/f19e0c852ba13694f5a79f3b719331051573cb5693feacf8a88ffffc3a71/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442", size = 385340, upload-time = "2026-06-30T07:17:18.928Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ae/7ec3a9d2d4351f99e37bcb06b6b6f954512646bfdbf9742e1de727865daf/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12", size = 372179, upload-time = "2026-06-30T07:17:20.539Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ac/9cee911dff2aaa9a5a8354f6610bf2e6a616de9197c5fff4f54f82585f1e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5", size = 379993, upload-time = "2026-06-30T07:17:22.212Z" }, + { url = "https://files.pythonhosted.org/packages/83/6b/7c2a07ba88d1e9a936612f7a5d067467ed03d971d5a06f7d309dff044a7e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf", size = 398909, upload-time = "2026-06-30T07:17:23.66Z" }, + { url = "https://files.pythonhosted.org/packages/97/0b/776ffcb66783637b0031f6d58d6fb55913c8b5abf00aeecd46bf933fb477/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00", size = 546584, upload-time = "2026-06-30T07:17:25.264Z" }, + { url = "https://files.pythonhosted.org/packages/55/33/ba3bc04d7092bd553c9b2b195624992d2cc4f3de1f380b7b93cbee67bd79/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef", size = 614357, upload-time = "2026-06-30T07:17:26.888Z" }, + { url = "https://files.pythonhosted.org/packages/8b/71/14edf065f04630b1a8472f7653cad03f6c478bcf95ea0e6aed55451e33ea/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a", size = 576533, upload-time = "2026-06-30T07:17:28.546Z" }, + { url = "https://files.pythonhosted.org/packages/ba/76/65002b08596c389105720a8c0d22298b8dc25a4baf89b2ce431343c8b1de/rpds_py-2026.6.3-cp315-cp315t-win32.whl", hash = "sha256:913ca42ccad3f8cc6e292b587ae8ae49c8c823e5dce51a736252fc7c7cdfa577", size = 201204, upload-time = "2026-06-30T07:17:30.193Z" }, + { url = "https://files.pythonhosted.org/packages/8c/97/d855d6b3c322d1f27e26f5241c42016b56cf01377ea8ed348285f54652f0/rpds_py-2026.6.3-cp315-cp315t-win_amd64.whl", hash = "sha256:ae3d4fe8c0b9213624fdce7279d70e3b148b682ca20719ebd193a23ebfa47324", size = 220719, upload-time = "2026-06-30T07:17:31.788Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "sse-starlette" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "starlette" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/be/0123026f719d1a7936f214a88b553bb5701e04ff2511147c1dab0c5035eb/sse_starlette-3.5.0.tar.gz", hash = "sha256:75de713aa8a9441513cc283220826da079d982770965b951e9437720e8bafdb2", size = 36794, upload-time = "2026-09-28T17:48:14.7Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/e4/cdda14023c316d71493bc54fdffc3dd006631b88866145c9d3cc33e0f1df/sse_starlette-3.5.0-py3-none-any.whl", hash = "sha256:3e6e1070df3f0f5d9cea81496de92dbb72f6721871d99748ece67441dd8b7997", size = 17407, upload-time = "2026-09-28T17:48:13.228Z" }, +] + +[[package]] +name = "starlette" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7b/2b/3850dc6bf7ef71b088962eba31dafc6cffd2f96e577ebb0bb316df96da3e/starlette-1.7.0.tar.gz", hash = "sha256:c79f74ea63cff761804fbbfb182f1e0b440c2d07b164d24700c5a1bab5d6ff5d", size = 2736246, upload-time = "2026-09-23T07:30:26.35Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/d6/1ec1b290f9e0fb067899b61e1d37a30c923068bad260b216dbe37a7d2967/starlette-1.7.0-py3-none-any.whl", hash = "sha256:67f8e99895493dd2911a03f11314af6ceebeae4e704bb9f43dfc6a9db151c93e", size = 78980, upload-time = "2026-09-23T07:30:24.567Z" }, +] + +[[package]] +name = "truststore" +version = "0.10.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/a3/1585216310e344e8102c22482f6060c7a6ea0322b63e026372e6dcefcfd6/truststore-0.10.4.tar.gz", hash = "sha256:9d91bd436463ad5e4ee4aba766628dd6cd7010cf3e2461756b3303710eebc301", size = 26169, upload-time = "2025-08-12T18:49:02.73Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/97/56608b2249fe206a67cd573bc93cd9896e1efb9e98bce9c163bcdc704b88/truststore-0.10.4-py3-none-any.whl", hash = "sha256:adaeaecf1cbb5f4de3b1959b42d41f6fab57b2b1666adb59e89cb0b53361d981", size = 18660, upload-time = "2025-08-12T18:49:01.46Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.54.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/34/30e9280707135d2cfc589dfff3cb796bd07a3aeb1a3e415ba09dd89d7bb4/uvicorn-0.54.0.tar.gz", hash = "sha256:a2e33cbfaa0306f8e6b0c13e0cb89d7d7a2da3e62b90c66e18c33d9807b28620", size = 112283, upload-time = "2026-09-25T06:52:37.601Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/0c/b54a4fdd7f90a3af8b02ebc9ce6712c2c208b7926a2f7bad95c33ebbe943/uvicorn-0.54.0-py3-none-any.whl", hash = "sha256:505bdb0f318731d45f1f712071fc781a8981f6847a31c902c9f5e652d4f67faf", size = 87427, upload-time = "2026-09-25T06:52:35.829Z" }, +] From b7b61079b3c4ee36b0933933d3e72ba88c4df6a8 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 11:55:28 -0400 Subject: [PATCH 02/14] Format Claude SDK runner without changing behavior --- examples/claude-runtime-sdk/worker.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/examples/claude-runtime-sdk/worker.py b/examples/claude-runtime-sdk/worker.py index 4fa7c3745..8dfdeadf7 100644 --- a/examples/claude-runtime-sdk/worker.py +++ b/examples/claude-runtime-sdk/worker.py @@ -115,12 +115,18 @@ def build_options(args: argparse.Namespace) -> ClaudeAgentOptions: auth_token = "omniroute-no-auth" if args.gateway_token_env is not None: if not re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", args.gateway_token_env): - raise ValueError("gateway-token-env must name an application environment variable") + raise ValueError( + "gateway-token-env must name an application environment variable" + ) if args.gateway_token_env.startswith("ANTHROPIC_"): - raise ValueError("use a gateway-specific token binding, separate from native Anthropic credentials") + raise ValueError( + "use a gateway-specific token binding, separate from native Anthropic credentials" + ) auth_token = os.environ.get(args.gateway_token_env) if not auth_token or not auth_token.strip(): - raise ValueError("the explicit gateway token environment binding is missing or empty") + raise ValueError( + "the explicit gateway token environment binding is missing or empty" + ) return ClaudeAgentOptions( system_prompt={"type": "preset", "preset": "claude_code"}, model=args.model, @@ -458,7 +464,9 @@ def main() -> int: if args.result_output is not None and args.result_output.exists(): raise ValueError("result-output must be a new private file") # This CLI process is the owned worker child, not the native coordinator. - configuration["native_anthropic_env_keys_removed"] = prepare_worker_environment() + configuration["native_anthropic_env_keys_removed"] = ( + prepare_worker_environment() + ) observation = anyio.run( lambda: run_worker( options, From 9edd76e9f9f817e818b59b7b5cfd16e329317ad0 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 11:46:00 -0400 Subject: [PATCH 03/14] feat(foundation): preserve executed OmniRoute Sol SDK worker source --- examples/omniroute-codex-sdk/worker.py | 245 ++++++++++++++++++++ examples/omniroute-codex-sdk/worker.py.lock | 115 +++++++++ 2 files changed, 360 insertions(+) create mode 100644 examples/omniroute-codex-sdk/worker.py create mode 100644 examples/omniroute-codex-sdk/worker.py.lock diff --git a/examples/omniroute-codex-sdk/worker.py b/examples/omniroute-codex-sdk/worker.py new file mode 100644 index 000000000..013b226c0 --- /dev/null +++ b/examples/omniroute-codex-sdk/worker.py @@ -0,0 +1,245 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.13,<3.14" +# dependencies = [ +# "openai-codex==0.159.2", +# ] +# /// +"""One native Codex SDK turn through an invocation-scoped OmniRoute provider. + +Derived from openai/codex rust-v0.159.2, commit +ff6aec96948b70d94983af2641a6b67c94faeff5, sdk/python/examples/{01,05,14}_* +and sdk/python/src/openai_codex/{api,client,_run}.py. See README.md for sources. +""" + +from __future__ import annotations + +import argparse +import asyncio +import json +import os +import re +import sys +import uuid +from collections import Counter +from pathlib import Path +from urllib.parse import urlsplit + +from openai_codex import ApprovalMode, AsyncCodex, CodexConfig, Sandbox +from openai_codex.types import ReasoningEffort + +SDK_VERSION = "0.159.2" +PROVIDER = "omniroute_runtime" +DEFAULT_MODEL = "cx/gpt-6.1-sol-max" +DEFAULT_BASE_URL = "http://127.0.0.1:20128/v1" +CLEANUP_TIMEOUT = 5.0 + + +def gateway_url(value: str) -> str: + """Keep the owned gateway and any explicit observer on HTTP loopback /v1.""" + parsed = urlsplit(value) + if ( + parsed.scheme != "http" + or parsed.hostname not in {"127.0.0.1", "localhost", "::1"} + or parsed.port is None + or parsed.username is not None + or parsed.password is not None + or parsed.query + or parsed.fragment + or parsed.path.rstrip("/") != "/v1" + ): + raise argparse.ArgumentTypeError("expected a port-qualified HTTP loopback /v1 URL") + return value.rstrip("/") + + +def request_id(value: str) -> str: + if not re.fullmatch(r"[A-Za-z0-9_.:-]{1,96}", value): + raise argparse.ArgumentTypeError("request id must be 1–96 ASCII identifier characters") + return value + + +def positive_seconds(value: str) -> float: + seconds = float(value) + if not 0 < seconds <= 3600: + raise argparse.ArgumentTypeError("timeout must be greater than zero and at most 3600 seconds") + return seconds + + +def runtime_config(args: argparse.Namespace) -> CodexConfig: + """Only the SDK child receives these supported native CLI overrides.""" + prefix = f"model_providers.{PROVIDER}." + quoted = lambda value: json.dumps(value, ensure_ascii=False) # noqa: E731 + overrides = ( + "model_provider=" + quoted(PROVIDER), + "model=" + quoted(args.model), + 'model_reasoning_effort="max"', + prefix + 'name="OmniRoute runtime workers"', + prefix + "base_url=" + quoted(args.base_url), + prefix + 'wire_api="responses"', + prefix + "requires_openai_auth=false", + prefix + "supports_websockets=false", + prefix + 'http_headers={"x-request-id"=' + quoted(args.request_id) + "}", + ) + if args.api_key_env: + if not re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", args.api_key_env): + raise ValueError("api-key-env must name an environment variable") + overrides += (prefix + "env_key=" + quoted(args.api_key_env),) + # Native retry settings remain native. The caller may disarm them for a + # measured acceptance attempt; there is no wrapper retry or agent loop. + if args.no_provider_retries: + overrides += (prefix + "request_max_retries=0", prefix + "stream_max_retries=0") + env = {"CONTEXT_MODE_PROJECT_DIR": str(args.workspace.resolve())} + if args.codex_home: + env["CODEX_HOME"] = str(args.codex_home.resolve()) + return CodexConfig( + codex_bin=str(args.codex_bin.resolve()) if args.codex_bin else None, + config_overrides=overrides, + cwd=str(args.workspace.resolve()), + env=env, + client_name="omniroute_codex_runtime_worker", + client_title="OmniRoute Codex runtime worker", + ) + + +def result_record(result) -> dict: + """Retain native snapshots; total is cumulative and last is not a turn sum.""" + kinds = Counter(item.model_dump(mode="json", by_alias=True).get("type") for item in result.items) + return { + "status": result.status.value, + "turn_id": result.id, + "final_response": result.final_response, + "duration_ms": result.duration_ms, + "item_counts": dict(kinds), + "usage_status": "reported" if result.usage is not None else "unknown", + "usage_scope": "native_thread_cumulative" if result.usage is not None else None, + "usage": result.usage.model_dump(mode="json", by_alias=True) if result.usage is not None else None, + } + + +def emit(value: dict) -> None: + print(json.dumps(value, ensure_ascii=False, separators=(",", ":")), flush=True) + + +async def run_worker(args: argparse.Namespace, prompt: str, *, sdk_factory=AsyncCodex, on_event=emit) -> dict: + """Use native start/resume/turn/interrupt/close, with one overall deadline.""" + codex = sdk_factory(config=runtime_config(args)) + turn = None + phase = "initialize" + record = { + "request_id": args.request_id, + "requested_model": args.model, + "requested_effort": "max", + "provider": PROVIDER, + "model_inference_submitted": False, + "usage_status": "unknown", + "usage_scope": None, + "usage": None, + } + try: + async with asyncio.timeout(args.timeout): + await codex.__aenter__() + server = codex.metadata.serverInfo + if server is None or server.version.split()[0] != SDK_VERSION: + raise RuntimeError("native runtime does not match the qualified SDK pin") + record["native_runtime"] = {"name": server.name, "version": server.version} + options = { + "cwd": str(args.workspace.resolve()), + "model": args.model, + "model_provider": PROVIDER, + "sandbox": Sandbox(args.sandbox), + "approval_mode": ApprovalMode(args.approval_mode), + } + phase = "thread_resume" if args.resume else "thread_start" + if args.resume: + thread = await codex.thread_resume(args.resume, **options) + else: + thread = await codex.thread_start(ephemeral=False, **options) + record["thread_id"] = thread.id + record["thread_mode"] = "resumed" if args.resume else "started" + selected = (await thread.read()).thread + if selected.model != args.model or selected.model_provider != PROVIDER: + raise RuntimeError("native thread did not retain the requested model and provider") + on_event({"event": "thread_ready", **record}) + phase = "turn_start" + # Codex owns tools, MCP discovery, skills, caching and compaction. + # There is no extra skill carrier or Responses prompt rewrite here. + record["model_inference_submitted"] = True + turn = await thread.turn(prompt, model=args.model, effort=ReasoningEffort.max) + phase = "turn_run" + result = await turn.run() + record.update(result_record(result)) + if args.native_result: + phase = "retain_native_result" + native = { + **record, + "items": [item.model_dump(mode="json", by_alias=True) for item in result.items], + } + fd = os.open(args.native_result, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600) + with os.fdopen(fd, "w", encoding="utf-8") as output: + json.dump(native, output, ensure_ascii=False, indent=2) + output.write("\n") + except (TimeoutError, asyncio.CancelledError) as exc: + record.update(status="deadline_exceeded" if isinstance(exc, TimeoutError) else "cancelled", phase=phase) + if turn is not None: + try: + await asyncio.wait_for(turn.interrupt(), CLEANUP_TIMEOUT) + record["interrupt_status"] = "requested" + except Exception as interrupt_error: + record["interrupt_status"] = type(interrupt_error).__name__ + if isinstance(exc, asyncio.CancelledError): + raise + except Exception as exc: + # Error messages may carry private tool/provider content. Leave them in + # native private state; the public-facing result retains type and phase. + record.update(status="failed", error_type=type(exc).__name__, phase=phase) + finally: + try: + await asyncio.wait_for(codex.close(), CLEANUP_TIMEOUT) + record["cleanup_status"] = "closed" + except Exception as exc: + record.update(status="cleanup_failed", cleanup_status=type(exc).__name__) + return record + + +def parse_args(argv=None) -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--workspace", type=Path, default=Path.cwd()) + parser.add_argument("--prompt", default="-", help="one bounded task, or - to read stdin") + parser.add_argument("--resume", help="native thread id from an earlier invocation") + parser.add_argument("--model", default=DEFAULT_MODEL, help="explicit native/gateway model id; default Sol/max route") + parser.add_argument("--base-url", type=gateway_url, default=DEFAULT_BASE_URL) + parser.add_argument("--request-id", type=request_id, default=uuid.uuid4().hex) + parser.add_argument("--timeout", type=positive_seconds, default=300.0) + parser.add_argument("--sandbox", choices=[Sandbox.read_only.value, Sandbox.workspace_write.value], default=Sandbox.workspace_write.value) + parser.add_argument("--approval-mode", choices=[mode.value for mode in ApprovalMode], default=ApprovalMode.deny_all.value) + parser.add_argument("--codex-bin", type=Path, help="explicit native 0.159.2 binary; defaults to the pinned SDK bundle") + parser.add_argument("--codex-home", type=Path, help="optional private worker config/state; inherited when omitted") + parser.add_argument("--api-key-env", help="optional gateway credential variable name; no credential value is accepted") + parser.add_argument("--no-provider-retries", action="store_true", help="disarm native request/stream retries for a measured attempt") + parser.add_argument("--native-result", type=Path, help="retain full native items in a new private 0600 file") + args = parser.parse_args(argv) + if not args.workspace.is_dir(): + parser.error("workspace must be an existing directory") + if args.codex_home and not args.codex_home.is_dir(): + parser.error("codex-home must be an existing private state directory") + if not args.model.strip(): + parser.error("model must be nonempty") + return args + + +def main() -> int: + args = parse_args() + prompt = sys.stdin.read() if args.prompt == "-" else args.prompt + if not prompt.strip(): + raise SystemExit("prompt must contain a bounded task") + try: + result = asyncio.run(run_worker(args, prompt)) + except KeyboardInterrupt: + emit({"event": "cancelled", "request_id": args.request_id, "usage_status": "unknown", "usage": None}) + return 130 + emit({"event": "result", **result}) + return 0 if result["status"] == "completed" else 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/examples/omniroute-codex-sdk/worker.py.lock b/examples/omniroute-codex-sdk/worker.py.lock new file mode 100644 index 000000000..66e1ef85d --- /dev/null +++ b/examples/omniroute-codex-sdk/worker.py.lock @@ -0,0 +1,115 @@ +version = 1 +revision = 3 +requires-python = ">=3.13, <3.14" + +[manifest] +requirements = [{ name = "openai-codex", specifier = "==0.159.2" }] + +[[package]] +name = "annotated-types" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" }, +] + +[[package]] +name = "openai-codex" +version = "0.159.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "openai-codex-cli-bin" }, + { name = "packaging" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/e5/b6a6a60a8b76d5b07e65fa3b696d14e3426959b2c6727218b1d6552a1499/openai_codex-0.159.2.tar.gz", hash = "sha256:65ba62eb39ad7ee6b77b9f240580d2ab9725a2789b02b2b2a252e852601ce6d2", size = 88976, upload-time = "2026-09-30T00:11:24.781Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/fd/89fa4ab1745e92dc8831f4a51ddc78ef216bfd5fcf3ca93c975c10555b77/openai_codex-0.159.2-py3-none-any.whl", hash = "sha256:03c5a0d7c1da9edc4b62d7b4973d6e8199ce9462a7dec9c6dc9d75a2a88d3786", size = 97109, upload-time = "2026-09-30T00:11:23.465Z" }, +] + +[[package]] +name = "openai-codex-cli-bin" +version = "0.159.2" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/b8/97b76d0c461b5b4d431fdf6074ebc096eba0867ae32b95c1a2eae4b60062/openai_codex_cli_bin-0.159.2-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:439b4cd51b8bd6767db020b363c8cbef2059a12e48f13f6bcbdfbab5da3b4b09", size = 132127936, upload-time = "2026-09-30T00:09:46.016Z" }, + { url = "https://files.pythonhosted.org/packages/4d/d1/acb27b8a7863278a95584c82d68cf489968c1a104a13005e74a46394aad6/openai_codex_cli_bin-0.159.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:458d95f02cf10522c5ed6f14c23889d5e9e7a11ea135ffd6a71be1678442bc53", size = 121303127, upload-time = "2026-09-30T00:09:56.277Z" }, + { url = "https://files.pythonhosted.org/packages/0f/cd/990c38f0f8c460c2d5b4c7364d3ff6d09c3d024926a98d412b882d82ebea/openai_codex_cli_bin-0.159.2-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:b821044ef54d028c6212d84473f72594aa437b6bb98ef428b7bf89e524765846", size = 129287242, upload-time = "2026-09-30T00:10:04.234Z" }, + { url = "https://files.pythonhosted.org/packages/1d/b1/6e09389842c1f84a6a0209a797ef44f627ce603f301f7bc0b60f09ee216d/openai_codex_cli_bin-0.159.2-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:0e33d45dc6f5dcdae3e1d6432fd85a4dfe38b26bd080b6b14c60daad120c4769", size = 138688522, upload-time = "2026-09-30T00:10:13.775Z" }, + { url = "https://files.pythonhosted.org/packages/15/31/c3aa4a8a6512e1a157d04191ce8b8a7b01a7bd7d62d8f829b126a5e6240e/openai_codex_cli_bin-0.159.2-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:2282e81f417bd09c89320a547592cbf0632fc64cf73df43c6d4ec78f1dfb0eef", size = 150278432, upload-time = "2026-09-30T00:10:23.929Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8d/999fe8295325466a6ed022026a4ffc1a2683ce7dd913bf45fcd7ceb0ae1e/openai_codex_cli_bin-0.159.2-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:028651fd690650161304a2f823f89440dce262abc4ab3b539bf0abb848a4fe59", size = 159968893, upload-time = "2026-09-30T00:10:33.713Z" }, + { url = "https://files.pythonhosted.org/packages/b4/70/7e20a73a1651345af2ee6e2d295693db68913f1a12229d7044a31d1bed2d/openai_codex_cli_bin-0.159.2-py3-none-win_amd64.whl", hash = "sha256:86f3e63325c9efefd13ae881e50e13673a55cbade7ba9f2eda085bf302d5e49b", size = 148571239, upload-time = "2026-09-30T00:10:43.196Z" }, + { url = "https://files.pythonhosted.org/packages/98/7f/2e2e96ff0333b4e18fb3f270b439525f6a5bfd767fc9d4ac5096af8d65bc/openai_codex_cli_bin-0.159.2-py3-none-win_arm64.whl", hash = "sha256:518cb998d9aae981ea82fdbbfdfbb0db13aa20c85abe68755bf106680e2f1bf9", size = 137400734, upload-time = "2026-09-30T00:10:52.388Z" }, +] + +[[package]] +name = "packaging" +version = "26.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" }, +] + +[[package]] +name = "pydantic" +version = "2.13.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/ef/fc4f868f4e2cee79f863883abffceff107875f569b848507319842d2a681/pydantic-2.13.5.tar.gz", hash = "sha256:51a9c5f7b2f8e636f04c6cada605d9b6a3bf1348fdf945a3d8869b19bba0ee08", size = 845750, upload-time = "2026-08-28T14:04:00.916Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/47/c95ffc2009878c7aac0c5e08528022dcb885933252a88b5f170058014464/pydantic-2.13.5-py3-none-any.whl", hash = "sha256:346a034f080da3755d8e9cb5e00e8b07de1d39e4f6e2c87d8ab7cafa0b269a73", size = 472589, upload-time = "2026-08-28T14:03:59.136Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/f9/8a06bea35ef8daf588f707784c973a7046e0034c8d8cfb08828eeffb8b75/pydantic_core-2.46.5.tar.gz", hash = "sha256:10416c15b8839ecc4ef4d0885da76da6fd0f67333a0eb8aff6d93c4b8f2910fc", size = 472262, upload-time = "2026-08-28T10:01:31.677Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f5/37/5abe39a8372a61d3dc3c1338fc504281c01b32fdb3169cd7187153b56d3e/pydantic_core-2.46.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:b7ca9034437b6022f941f4857459562ee00a560b97e7cce8a0ec5a74fc6766e0", size = 2075885, upload-time = "2026-08-28T09:58:47.856Z" }, + { url = "https://files.pythonhosted.org/packages/21/43/6323b1f8b217780454c61304bcd2b38ae4762f50754414124603ccc90bb2/pydantic_core-2.46.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f332f0e72a5a0400141f830744e141bf9f97917878dbe968669e8a7fefea78ff", size = 1922768, upload-time = "2026-08-28T09:58:49.58Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a3/c05ca796e1197618a774b01e596aeedfefc2f7d8c01ae3054e910b120e8a/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:193375f3548919d3f0b60936ca113ada3e38f264f91b9b8e0508efaad57be931", size = 1951241, upload-time = "2026-08-28T09:58:51.511Z" }, + { url = "https://files.pythonhosted.org/packages/68/32/33bc39ac705c52cffc908e8389f9754fdb208aea5c69cceddf4eb3ce99af/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79bdfa52f843137045b2d081cc05c120ba6665d29b7559c2c47690906f39279f", size = 2031975, upload-time = "2026-08-28T09:58:53.166Z" }, + { url = "https://files.pythonhosted.org/packages/b0/70/2333e885c0f6a67bc105c5916965dac9b57f2718ee20d81d1a06a4ebdc13/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24922243639cbdac66c75fcb6fd6495a9cb52b213d62f9a0d16f0310b1ff8038", size = 2208542, upload-time = "2026-08-28T09:58:55.017Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ea/296debfb4264207bbda5936133892e027c0a58875ad53ebd512fba8ec3a2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c76fe65e607be28c7fd4d56fc3c42b1583aa058ce3408b7ad0fd540171d31f9f", size = 2264692, upload-time = "2026-08-28T09:58:56.767Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f2/9e4de77a6271e07a76d2d58b11c091a979c191ed2939bf80067568b369d2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f7b393a8b3da82f5c1fc0751e6d01ac6c55b93c18226a60bdfba4a724efafd1", size = 2066633, upload-time = "2026-08-28T09:58:58.531Z" }, + { url = "https://files.pythonhosted.org/packages/8d/db/f9e9d0c97445987b2084823d5c240de88087338f04fc2cfaa2df186b8049/pydantic_core-2.46.5-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:7ac031912d54f3d83ef3b3eb98dfabc1608802e2202263d25957eeed40b94761", size = 2105235, upload-time = "2026-08-28T09:59:00.421Z" }, + { url = "https://files.pythonhosted.org/packages/07/c5/79169b047b3b2c3e99e04bc76372af9637e0bf6db638274fa927df96369e/pydantic_core-2.46.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:837b396ca3d7b74091ca623f6cbd8351bd42d670a79c2683e79fb089f06a2de5", size = 2157367, upload-time = "2026-08-28T09:59:02.442Z" }, + { url = "https://files.pythonhosted.org/packages/26/b5/ba6057afb7c291bd449f51b867f95aef2072941c4ce4e5c31d6ffd132d3b/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:5ee239d575f80b08eca11f6e20f90c4c695de7825c67eefe6091fbf20dda648e", size = 2158420, upload-time = "2026-08-28T09:59:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/6e/28/2057abecaafdc22912afa819603a51f0a62d40643b7c4871c51721fea9be/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:e80675d75ae2cd14372cb65cad5400d9347a3d3f6c13000183f22dfd027283ed", size = 2309588, upload-time = "2026-08-28T09:59:06.048Z" }, + { url = "https://files.pythonhosted.org/packages/71/9d/881156dc404e27479c4246128d73538464cab4a239bec61995e227644c30/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c4b71f10dd532fb7a5cbc8f58707779e64f03a258c2bf8bfbaecfcd9970b519", size = 2341866, upload-time = "2026-08-28T09:59:08.539Z" }, + { url = "https://files.pythonhosted.org/packages/5a/38/d66f443a259f84d13babdceae568e572b0ed26da17ca5d0a649ebb110a67/pydantic_core-2.46.5-cp313-cp313-win32.whl", hash = "sha256:97bf8de4d541598c94a59344eeb988a94c08ff76b5723c41f6567ec18c7892ea", size = 1938580, upload-time = "2026-08-28T09:59:10.402Z" }, + { url = "https://files.pythonhosted.org/packages/2c/1e/1d5371213f4cc9a7ed70c0bfcc7911de22311ee99a662a56077d7292d2ac/pydantic_core-2.46.5-cp313-cp313-win_amd64.whl", hash = "sha256:15f4a94963c95accac15b7b657bb177d3ad82bb90b0d0526d9a9b85079925db5", size = 2041980, upload-time = "2026-08-28T09:59:12.396Z" }, + { url = "https://files.pythonhosted.org/packages/5a/48/4222d90b1c67568bace4dec6dca6271449c66de3595d72b6d098f5fde597/pydantic_core-2.46.5-cp313-cp313-win_arm64.whl", hash = "sha256:d22a945598fb91236b4dd793a6e42e4f3dd7740bb5aace5ebd7d4c08d13bb575", size = 1997213, upload-time = "2026-08-28T09:59:14.245Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, +] From 0f2949f5a6b5f27b1ffed0c094f63930226b337e Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 11:55:27 -0400 Subject: [PATCH 04/14] test(foundation): qualify native OmniRoute SDK transport and lifecycle --- examples/omniroute-codex-sdk/README.md | 149 +++++++++ examples/omniroute-codex-sdk/checks.json | 89 ++++++ examples/omniroute-codex-sdk/test_worker.py | 285 ++++++++++++++++++ .../omniroute-codex-sdk/test_worker.py.lock | 115 +++++++ examples/omniroute-codex-sdk/worker.py | 75 ++++- 5 files changed, 699 insertions(+), 14 deletions(-) create mode 100644 examples/omniroute-codex-sdk/README.md create mode 100644 examples/omniroute-codex-sdk/checks.json create mode 100644 examples/omniroute-codex-sdk/test_worker.py create mode 100644 examples/omniroute-codex-sdk/test_worker.py.lock diff --git a/examples/omniroute-codex-sdk/README.md b/examples/omniroute-codex-sdk/README.md new file mode 100644 index 000000000..8f721bd54 --- /dev/null +++ b/examples/omniroute-codex-sdk/README.md @@ -0,0 +1,149 @@ +# Native Codex SDK worker through OmniRoute + +This foundation worker can be called from a native Claude coordinator. It uses +the maintained Codex harness through the official Python SDK, with Sol/max as +the primary worker and an invocation-scoped OmniRoute Responses provider. +The existing Codex integration remains the incumbent; this example does not +select a winner in the separate SDK comparison. + +## Run one bounded task + +The PEP 723 scripts and adjacent locks pin `openai-codex==0.159.2`, including +its matching native CLI. Use the existing selected gateway and a task worktree. +Run from the repository root: + +```sh +rtk uv run --locked --script examples/omniroute-codex-sdk/worker.py \ + --workspace "$WORKER_PROJECT" \ + --codex-home "$PRIVATE_WORKER_HOME" \ + --prompt - +``` + +The default endpoint is the selected loopback gateway at port 20128. An owned +reverse observer can be supplied with `--base-url`; the worker never changes +gateway compression engines or native coordinator configuration. The default +model is the explicit `cx/gpt-6.1-sol-max` route, with native reasoning effort +`max` at launch and turn start. Preserving the native prefix is important for +cache reuse; no prompt rewrite, extra skill carrier or outer agent loop is added. + +Pass one bounded task on stdin. The worker emits a compact `thread_ready` JSON +line before the turn, then a result with the final answer, item counts and native +usage. To retain the actual full tool items, add `--native-result` with a new +private output path. The writer creates it with mode 0600 and refuses overwrite. +Raw tool output and private thread IDs stay outside public evidence. + +`--sandbox workspace-write` and `--approval-mode deny_all` are the defaults: +native tools can work within the selected sandbox, and approval requests are +denied. The supported `auto_review` mode is available for a caller that has +qualified its native approval reviewer and accounting. This is separate from an +explicit Astra judgment stage. The worker preserves existing native MCP/tool +configuration; an empty private Codex home does not qualify those integrations. + +Use `--codex-bin` only for an explicit matching native 0.159.2 binary. An omitted +`--codex-home` inherits the native home; supplying it scopes worker configuration +and recoverable state to the child process. The example neither reads nor copies +authentication stores. The selected keyless loopback gateway owns its upstream +account handling; for another accepted gateway configuration, `--api-key-env` +names an existing credential variable without accepting or printing its value. + +## Resume, judgment and recovery + +Retain the native thread ID privately and resume with the same project, worker +home and route: + +```sh +rtk uv run --locked --script examples/omniroute-codex-sdk/worker.py \ + --workspace "$WORKER_PROJECT" \ + --codex-home "$PRIVATE_WORKER_HOME" \ + --resume "$WORKER_THREAD_ID" \ + --prompt - +``` + +Use Astra/max explicitly for consequential architecture, conflicting primary +evidence or a failure remaining after one bounded Sol repair. Record the trigger +and acceptance result with that task, then pass `--model cx/gpt-6-astra-max`. +Explicit model choices are retained; the example never silently retries with +another model or claims that an advertised model is an entitlement check. + +One overall deadline bounds initialization, thread start/resume and the turn. +On a deadline the caller requests the native turn interrupt, then closes its SDK +child. Unknown usage stays unknown. Native provider retries remain native; +`--no-provider-retries` disarms request/stream retries for a measured attempt. +The example runs one Python process per invocation and keeps persistent native +state available for resume. Cleanup terminates only its owned app-server child. + +## Skills and token practice + +For installing or activating selected skills, use +[the existing lifecycle](../../adoption/skills/lifecycle.md) and +[the runtime-worker skill recipe](../../blueprints/runtime-workers/skills/README.md). +Use the selected installer and manifest rather than another skill loader. Codex +discovers project `.agents/skills` and applies its native skill description and +invocation policies. A Claude-only bridge read explicitly by a worker is an +explicit read, not proof of Codex implicit discovery. Keep the availability, +actual instruction read and task outcome as separate observations. + +RTK, context-mode and other selected tools follow their existing task conditions +and native configuration. Load the selected `SKILL.md` before using its workflow; +do not preload every skill body or enable every optional MCP service. The example +sets context-mode's existing project-directory carrier only for its child. + +The emitted `usage.total` is a cumulative native thread snapshot, including past +turns on resume. `usage.last` is the last model response, not a complete multi-call +turn sum. Count the latest cumulative snapshot once, or difference comparable +snapshots. Cached input and reasoning output are subsets; never add them again. +These native snapshots do not establish complete gateway/provider usage, cache +billing, backend identity or a measured compression benefit. + +## Local checks and their limits + +```sh +rtk uv run --locked --script examples/omniroute-codex-sdk/test_worker.py +``` + +These authored local integration fixtures use the real pinned SDK and native CLI +against an authored loopback SSE provider. They check request model/effort, +own-request headers, native tool carriage, stable cache/prefix identity across +resume, cumulative counters, deadline interruption, kernel-observed owned-child +exit and private original-result retention. Missing terminal events and an +unsupported `wire_api` are discriminating negative controls. They are not +unchanged upstream tests, live model runs or a full SDK/framework comparison. + +The first local oracle failed with `KeyError: 'tools'`. Original tagged source +and actual wire inspection corrected it: Sol/Astra use native ResponsesLite, +which carries `input[].type=additional_tools`; absence of a top-level `tools` +field does not mean tools are absent. Those prefix item IDs hash visible payloads +within the thread, so native retry/resume preserves their identity. The corrected +oracle checks that native form and preserves it unchanged. + +The pinned SDK emits `ResourceWarning` for unclosed stdout/stderr handles in +repeated same-Python-process fixture calls. Its native `close()` closes stdin, +terminates/waits for its app-server and joins readers; it does not explicitly +close stdout/stderr. The standalone invocation and kernel PID checks bound the +owned process lifecycle. A long-running in-process SDK pool is not qualified by +this example. The existing upstream qualification also retains its one unrelated +formatter-driver test failure; no whole-suite passing claim is made here. + +## Sources and installation + +- [openai/codex `rust-v0.159.2`](https://github.com/openai/codex/tree/ff6aec96948b70d94983af2641a6b67c94faeff5/sdk/python), + immutable commit `ff6aec96948b70d94983af2641a6b67c94faeff5`: maintained SDK, + its constructor/resume/turn-control examples and native installation commands. +- [SDK transport/configuration](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/sdk/python/src/openai_codex/client.py) + and [native provider fields](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/model-provider-info/src/lib.rs): + child-only CLI overrides, native lifecycle, Responses, headers and optional + environment-key authentication. +- [Native namespaced model matching](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/models-manager/src/manager.rs#L763) + and [bundled model metadata](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/models-manager/models.json): + the single `cx/` namespace and `-max` suffix retain the longest-matching native + Sol/Astra capability row; this does not attest the gateway's backend routing. +- [Native ResponsesLite prefix assembly](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/core/src/client.rs#L902) + and [SSE fixture helpers](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/core/tests/common/responses.rs#L753): + native tool/prefix preservation and the source of the authored local fixture. +- [Published SDK 0.159.2](https://pypi.org/pypi/openai-codex/0.159.2/json): wheel + SHA-256 `03c5a0d7c1da9edc4b62d7b4973d6e8199ce9462a7dec9c6dc9d75a2a88d3786`. + The adjacent locks are generated by supported `uv add --script` and + `uv lock --script` commands; execution uses `uv run --locked --script`. +- [Existing SDK installation and source qualification](https://github.com/seathatflowsinourveins/native-agent-stack/blob/404b821cd3af25800ea418dc6145cc5cb6fe33c5/evidence/artifacts/runtime-sdk-20260930/receipt.json): + preserved matching SDK/CLI pins, native custom-provider reference, + 21 unchanged published Python source files and retained upstream test results. diff --git a/examples/omniroute-codex-sdk/checks.json b/examples/omniroute-codex-sdk/checks.json new file mode 100644 index 000000000..24e09e0e8 --- /dev/null +++ b/examples/omniroute-codex-sdk/checks.json @@ -0,0 +1,89 @@ +{ + "schema_version": 1, + "evidence_class": "local_integration_synthetic_provider", + "checked_on": "2026-09-30", + "scope": "Real official SDK and bundled native CLI against an authored loopback SSE fixture. No live model/provider execution and no SDK comparison-winner claim.", + "sources": [ + { + "repository": "https://github.com/openai/codex", + "ref": "rust-v0.159.2", + "commit": "ff6aec96948b70d94983af2641a6b67c94faeff5", + "paths": [ + "sdk/python/src/openai_codex/client.py", + "sdk/python/src/openai_codex/api.py", + "sdk/python/src/openai_codex/_run.py", + "codex-rs/core/src/client.rs", + "codex-rs/core/tests/common/responses.rs", + "codex-rs/models-manager/src/manager.rs" + ] + } + ], + "versions": { + "sdk": "0.159.2", + "native_cli": "0.159.2", + "python": "3.13.15", + "uv": "0.12.17", + "ruff": "0.15.8", + "host_scope": "Linux x86_64 glibc" + }, + "source_closure": { + "executed_worker_commit": "3c51e33", + "executed_worker_sha256": "aa960eca54f3cb098d74deb63673f6ecf4bcf747ef030b16ee00e4a093c40763", + "formatted_worker_sha256": "8dfa1799dc2ce034548eb2581befe61bef480728cc541a451e960bb48decc651", + "ast_identical": true, + "worker_lock_sha256": "15e5e7cfeec11ac86d8f081742c726c0d70326b480894a81e5cc76a7d9225c44", + "worker_lock_unchanged": true + }, + "attempts": [ + { + "id": "original-tool-oracle", + "command": "rtk uv run --locked --script examples/omniroute-codex-sdk/test_worker.py", + "exit_code": 1, + "actual_returned_excerpt": "Ran 6 tests in 9.356s\nFAILED (errors=1)\nKeyError: 'tools'", + "correction": "Original tagged core/src/client.rs:902-933 and actual local request inspection show native ResponsesLite tools in input[].type=additional_tools. A missing top-level tools key is not tool absence." + }, + { + "id": "corrected-tool-oracle", + "command": "rtk uv run --locked --script examples/omniroute-codex-sdk/test_worker.py", + "exit_code": 0, + "actual_returned_excerpt": "Ran 6 tests in 9.293s\nOK" + }, + { + "id": "independent-owned-child-observation", + "command": "rtk uv run --locked --script examples/omniroute-codex-sdk/test_worker.py", + "exit_code": 0, + "actual_returned_excerpt": "Ran 6 tests in 11.615s\nOK", + "additional_observation": "Each observed owned SDK app-server PID returned ProcessLookupError from os.kill(pid, 0) after native close. No private SDK transport mutation." + }, + { + "id": "initial-import-order-lint", + "command": "rtk uvx --from ruff==0.15.8 ruff check --select E,F,I,B,C4 --ignore E501 examples/omniroute-codex-sdk/worker.py examples/omniroute-codex-sdk/test_worker.py", + "exit_code": 1, + "actual_returned_excerpt": "I001 [*] Import block is un-sorted or un-formatted\nFound 1 error.", + "correction": "Supported ruff check --select I --fix organized the local test imports; worker source was unchanged." + }, + { + "id": "final-lint", + "command": "rtk uvx --from ruff==0.15.8 ruff check --select E,F,I,B,C4 --ignore E501 examples/omniroute-codex-sdk/worker.py examples/omniroute-codex-sdk/test_worker.py", + "exit_code": 0, + "actual_returned_excerpt": "All checks passed!" + }, + { + "id": "final-format", + "command": "rtk uvx --from ruff==0.15.8 ruff format --check --line-length 100 examples/omniroute-codex-sdk/worker.py examples/omniroute-codex-sdk/test_worker.py", + "exit_code": 0, + "actual_returned_excerpt": "2 files already formatted" + } + ], + "negative_controls": [ + "A provider stream missing response.completed is rejected by the same completed-result check, with usage unknown and native child closed.", + "Unsupported wire_api=chat is rejected during native initialization, before any provider request.", + "An existing native-result artifact is rejected without overwriting its original bytes." + ], + "limitations": [ + "Fixture token values are authored data for cumulative/subset accounting; they are not measured provider usage or billing.", + "The pinned SDK emits ResourceWarning for unclosed stdout/stderr file handles during repeated same-Python-process fixture calls. Native child termination is independently observed. A long-lived in-process SDK pool remains unqualified.", + "MCP/tool/skill availability follows caller-native configuration and loading policies. This isolated fixture does not qualify the complete optional stack.", + "The existing unchanged upstream SDK qualification retains one formatter-driver test failure; these local checks do not replace it." + ] +} diff --git a/examples/omniroute-codex-sdk/test_worker.py b/examples/omniroute-codex-sdk/test_worker.py new file mode 100644 index 000000000..13a658b1c --- /dev/null +++ b/examples/omniroute-codex-sdk/test_worker.py @@ -0,0 +1,285 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.13,<3.14" +# dependencies = [ +# "openai-codex==0.159.2", +# ] +# /// +"""Local integration fixtures, not upstream tests or provider/model acceptance. + +The SSE fixture derives from openai/codex rust-v0.159.2 +codex-rs/core/tests/common/responses.rs::{sse,ev_response_created, +ev_assistant_message,ev_completed}. The SDK and bundled native runtime are real; +the loopback provider returns authored deterministic fixture responses. +""" + +import asyncio +import json +import os +import tempfile +import threading +import unittest +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from pathlib import Path + +import worker +from openai_codex import AsyncCodex + + +class FixtureGateway: + def __init__(self, mode="complete"): + self.mode = mode + self.requests = [] + self.release = threading.Event() + owner = self + + class Handler(BaseHTTPRequestHandler): + def log_message(self, *args): + pass + + def do_POST(self): + body = json.loads(self.rfile.read(int(self.headers["Content-Length"]))) + index = len(owner.requests) + owner.requests.append( + { + "path": self.path, + "body": body, + "request_id": self.headers.get("x-request-id"), + "has_authorization": "authorization" in self.headers, + } + ) + response_id = f"fixture_response_{index}" + events = [ + {"type": "response.created", "response": {"id": response_id}}, + { + "type": "response.output_item.done", + "item": { + "type": "message", + "role": "assistant", + "id": f"fixture_message_{index}", + "content": [{"type": "output_text", "text": f"fixture answer {index}"}], + }, + }, + ] + if owner.mode == "complete": + input_tokens, cached_tokens, output_tokens, reasoning_tokens = ( + (20, 5, 4, 2) if index == 0 else (30, 10, 6, 4) + ) + events.append( + { + "type": "response.completed", + "response": { + "id": response_id, + "usage": { + "input_tokens": input_tokens, + "input_tokens_details": {"cached_tokens": cached_tokens}, + "output_tokens": output_tokens, + "output_tokens_details": {"reasoning_tokens": reasoning_tokens}, + "total_tokens": input_tokens + output_tokens, + }, + }, + } + ) + encoded = "".join( + f"event: {event['type']}\ndata: {json.dumps(event)}\n\n" for event in events + ).encode() + self.send_response(200) + self.send_header("Content-Type", "text/event-stream") + self.send_header("Content-Length", str(len(encoded))) + self.end_headers() + if owner.mode == "stall": + owner.release.wait(10) + try: + self.wfile.write(encoded) + except (BrokenPipeError, ConnectionResetError): + pass + + self.server = ThreadingHTTPServer(("127.0.0.1", 0), Handler) + self.server.daemon_threads = True + self.thread = threading.Thread(target=self.server.serve_forever, daemon=True) + self.url = f"http://127.0.0.1:{self.server.server_port}/v1" + + def __enter__(self): + self.thread.start() + return self + + def __exit__(self, *args): + self.release.set() + self.server.shutdown() + self.server.server_close() + self.thread.join(2) + + +class NativeTransportTests(unittest.TestCase): + def setUp(self): + self.temp = tempfile.TemporaryDirectory() + self.addCleanup(self.temp.cleanup) + self.project = Path(self.temp.name) / "project" + self.home = Path(self.temp.name) / "codex-home" + self.project.mkdir() + self.home.mkdir(mode=0o700) + + def args(self, gateway, *extra): + return worker.parse_args( + [ + "--workspace", + str(self.project), + "--codex-home", + str(self.home), + "--base-url", + gateway.url, + "--request-id", + "fixture-owned-request", + "--sandbox", + "read-only", + "--timeout", + "15", + "--no-provider-retries", + *extra, + ] + ) + + def run_worker(self, args, *, sdk_factory=AsyncCodex): + events = [] + instances, owned_pids = [], [] + + def create_sdk(config): + instance = sdk_factory(config=config) + instances.append(instance) + return instance + + def observe(event): + events.append(event) + # Observation only: inspect the PID of this test's own SDK child. + # Native source: sdk/python/src/openai_codex/client.py::_start_process. + process = instances[-1]._client._sync._proc + if process is not None: + owned_pids.append(process.pid) + + result = asyncio.run( + worker.run_worker( + args, "One bounded fixture task.", sdk_factory=create_sdk, on_event=observe + ) + ) + for pid in owned_pids: + with self.assertRaises(ProcessLookupError): + os.kill(pid, 0) + return result, events + + def assert_accepted(self, result): + self.assertEqual(result["status"], "completed", result) + self.assertEqual(result["cleanup_status"], "closed", result) + self.assertEqual(result["usage_status"], "reported", result) + self.assertEqual(result["usage_scope"], "native_thread_cumulative", result) + + def test_native_payload_header_tools_and_nonadditive_resume(self): + with FixtureGateway() as gateway: + first, events = self.run_worker(self.args(gateway)) + self.assert_accepted(first) + self.assertEqual(first["final_response"], "fixture answer 0") + self.assertEqual(events[0]["event"], "thread_ready") + second, _ = self.run_worker(self.args(gateway, "--resume", first["thread_id"])) + self.assert_accepted(second) + self.assertEqual(second["thread_id"], first["thread_id"]) + self.assertEqual(second["thread_mode"], "resumed") + self.assertEqual(len(gateway.requests), 2) + for request in gateway.requests: + self.assertEqual(request["path"], "/v1/responses") + self.assertEqual(request["request_id"], "fixture-owned-request") + self.assertFalse(request["has_authorization"]) + self.assertEqual(request["body"]["model"], worker.DEFAULT_MODEL) + self.assertEqual(request["body"]["reasoning"]["effort"], "max") + # Native Sol/Astra ResponsesLite carries tools inside input. + # Source: core/src/client.rs:902–933 at rust-v0.159.2. + tool_prefix = request["body"]["input"][0] + self.assertEqual(tool_prefix["type"], "additional_tools") + self.assertTrue(tool_prefix["tools"]) + self.assertIn("functions", [tool.get("name") for tool in tool_prefix["tools"]]) + self.assertEqual( + gateway.requests[0]["body"]["prompt_cache_key"], + gateway.requests[1]["body"]["prompt_cache_key"], + ) + self.assertEqual( + gateway.requests[0]["body"]["input"][0]["id"], + gateway.requests[1]["body"]["input"][0]["id"], + ) + self.assertIn("fixture answer 0", json.dumps(gateway.requests[1]["body"]["input"])) + first_total, second_total = first["usage"]["total"], second["usage"]["total"] + self.assertEqual(first_total["inputTokens"], 20) + self.assertEqual(first_total["outputTokens"], 4) + self.assertEqual(first_total["cachedInputTokens"], 5) + self.assertEqual(first_total["reasoningOutputTokens"], 2) + self.assertEqual(second_total["inputTokens"], 50) + self.assertEqual(second_total["outputTokens"], 10) + self.assertEqual(second_total["cachedInputTokens"], 15) + self.assertEqual(second_total["reasoningOutputTokens"], 6) + # Cached/reasoning counters are subsets; never add them to total. + self.assertEqual(second_total["totalTokens"], 60) + self.assertEqual(second["usage"]["last"]["totalTokens"], 36) + + def test_explicit_astra_model_is_preserved(self): + with FixtureGateway() as gateway: + selected = "cx/gpt-6-astra-max" + result, _ = self.run_worker(self.args(gateway, "--model", selected)) + self.assert_accepted(result) + self.assertEqual(gateway.requests[0]["body"]["model"], selected) + self.assertEqual(gateway.requests[0]["body"]["reasoning"]["effort"], "max") + + def test_incomplete_stream_negative_control_fails_acceptance(self): + with FixtureGateway("incomplete") as gateway: + result, _ = self.run_worker(self.args(gateway)) + with self.assertRaises(AssertionError): + self.assert_accepted(result) + self.assertEqual(result["status"], "failed", result) + self.assertEqual(result["usage_status"], "unknown") + self.assertIsNone(result["usage"]) + self.assertEqual(len(gateway.requests), 1) + self.assertEqual(result["cleanup_status"], "closed") + + def test_wrong_wire_api_negative_control_never_submits(self): + def wrong_provider(config): + config.config_overrides = tuple( + value.replace('wire_api="responses"', 'wire_api="chat"') + for value in config.config_overrides + ) + return AsyncCodex(config=config) + + with FixtureGateway() as gateway: + result, _ = self.run_worker(self.args(gateway), sdk_factory=wrong_provider) + with self.assertRaises(AssertionError): + self.assert_accepted(result) + self.assertEqual(result["status"], "failed", result) + self.assertEqual(result["phase"], "initialize") + self.assertFalse(result["model_inference_submitted"]) + self.assertIsNone(result["usage"]) + self.assertFalse(gateway.requests) + self.assertEqual(result["cleanup_status"], "closed") + + def test_deadline_interrupts_native_turn_and_closes(self): + with FixtureGateway("stall") as gateway: + result, _ = self.run_worker(self.args(gateway, "--timeout", "2")) + self.assertEqual(result["status"], "deadline_exceeded", result) + self.assertEqual(result["interrupt_status"], "requested", result) + self.assertEqual(result["cleanup_status"], "closed") + self.assertEqual(result["usage_status"], "unknown") + self.assertIsNone(result["usage"]) + + def test_native_artifact_is_private_and_never_overwritten(self): + destination = Path(self.temp.name) / "native-result.json" + with FixtureGateway() as gateway: + args = self.args(gateway, "--native-result", str(destination)) + result, _ = self.run_worker(args) + self.assert_accepted(result) + retained = destination.read_bytes() + native = json.loads(retained) + self.assertTrue(native["items"]) + self.assertEqual(destination.stat().st_mode & 0o777, 0o600) + duplicate, _ = self.run_worker(args) + self.assertEqual(duplicate["status"], "failed", duplicate) + self.assertEqual(duplicate["phase"], "retain_native_result") + self.assertEqual(duplicate["error_type"], "FileExistsError") + self.assertEqual(destination.read_bytes(), retained) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/examples/omniroute-codex-sdk/test_worker.py.lock b/examples/omniroute-codex-sdk/test_worker.py.lock new file mode 100644 index 000000000..66e1ef85d --- /dev/null +++ b/examples/omniroute-codex-sdk/test_worker.py.lock @@ -0,0 +1,115 @@ +version = 1 +revision = 3 +requires-python = ">=3.13, <3.14" + +[manifest] +requirements = [{ name = "openai-codex", specifier = "==0.159.2" }] + +[[package]] +name = "annotated-types" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" }, +] + +[[package]] +name = "openai-codex" +version = "0.159.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "openai-codex-cli-bin" }, + { name = "packaging" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/e5/b6a6a60a8b76d5b07e65fa3b696d14e3426959b2c6727218b1d6552a1499/openai_codex-0.159.2.tar.gz", hash = "sha256:65ba62eb39ad7ee6b77b9f240580d2ab9725a2789b02b2b2a252e852601ce6d2", size = 88976, upload-time = "2026-09-30T00:11:24.781Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/fd/89fa4ab1745e92dc8831f4a51ddc78ef216bfd5fcf3ca93c975c10555b77/openai_codex-0.159.2-py3-none-any.whl", hash = "sha256:03c5a0d7c1da9edc4b62d7b4973d6e8199ce9462a7dec9c6dc9d75a2a88d3786", size = 97109, upload-time = "2026-09-30T00:11:23.465Z" }, +] + +[[package]] +name = "openai-codex-cli-bin" +version = "0.159.2" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/b8/97b76d0c461b5b4d431fdf6074ebc096eba0867ae32b95c1a2eae4b60062/openai_codex_cli_bin-0.159.2-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:439b4cd51b8bd6767db020b363c8cbef2059a12e48f13f6bcbdfbab5da3b4b09", size = 132127936, upload-time = "2026-09-30T00:09:46.016Z" }, + { url = "https://files.pythonhosted.org/packages/4d/d1/acb27b8a7863278a95584c82d68cf489968c1a104a13005e74a46394aad6/openai_codex_cli_bin-0.159.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:458d95f02cf10522c5ed6f14c23889d5e9e7a11ea135ffd6a71be1678442bc53", size = 121303127, upload-time = "2026-09-30T00:09:56.277Z" }, + { url = "https://files.pythonhosted.org/packages/0f/cd/990c38f0f8c460c2d5b4c7364d3ff6d09c3d024926a98d412b882d82ebea/openai_codex_cli_bin-0.159.2-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:b821044ef54d028c6212d84473f72594aa437b6bb98ef428b7bf89e524765846", size = 129287242, upload-time = "2026-09-30T00:10:04.234Z" }, + { url = "https://files.pythonhosted.org/packages/1d/b1/6e09389842c1f84a6a0209a797ef44f627ce603f301f7bc0b60f09ee216d/openai_codex_cli_bin-0.159.2-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:0e33d45dc6f5dcdae3e1d6432fd85a4dfe38b26bd080b6b14c60daad120c4769", size = 138688522, upload-time = "2026-09-30T00:10:13.775Z" }, + { url = "https://files.pythonhosted.org/packages/15/31/c3aa4a8a6512e1a157d04191ce8b8a7b01a7bd7d62d8f829b126a5e6240e/openai_codex_cli_bin-0.159.2-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:2282e81f417bd09c89320a547592cbf0632fc64cf73df43c6d4ec78f1dfb0eef", size = 150278432, upload-time = "2026-09-30T00:10:23.929Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8d/999fe8295325466a6ed022026a4ffc1a2683ce7dd913bf45fcd7ceb0ae1e/openai_codex_cli_bin-0.159.2-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:028651fd690650161304a2f823f89440dce262abc4ab3b539bf0abb848a4fe59", size = 159968893, upload-time = "2026-09-30T00:10:33.713Z" }, + { url = "https://files.pythonhosted.org/packages/b4/70/7e20a73a1651345af2ee6e2d295693db68913f1a12229d7044a31d1bed2d/openai_codex_cli_bin-0.159.2-py3-none-win_amd64.whl", hash = "sha256:86f3e63325c9efefd13ae881e50e13673a55cbade7ba9f2eda085bf302d5e49b", size = 148571239, upload-time = "2026-09-30T00:10:43.196Z" }, + { url = "https://files.pythonhosted.org/packages/98/7f/2e2e96ff0333b4e18fb3f270b439525f6a5bfd767fc9d4ac5096af8d65bc/openai_codex_cli_bin-0.159.2-py3-none-win_arm64.whl", hash = "sha256:518cb998d9aae981ea82fdbbfdfbb0db13aa20c85abe68755bf106680e2f1bf9", size = 137400734, upload-time = "2026-09-30T00:10:52.388Z" }, +] + +[[package]] +name = "packaging" +version = "26.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" }, +] + +[[package]] +name = "pydantic" +version = "2.13.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/ef/fc4f868f4e2cee79f863883abffceff107875f569b848507319842d2a681/pydantic-2.13.5.tar.gz", hash = "sha256:51a9c5f7b2f8e636f04c6cada605d9b6a3bf1348fdf945a3d8869b19bba0ee08", size = 845750, upload-time = "2026-08-28T14:04:00.916Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/47/c95ffc2009878c7aac0c5e08528022dcb885933252a88b5f170058014464/pydantic-2.13.5-py3-none-any.whl", hash = "sha256:346a034f080da3755d8e9cb5e00e8b07de1d39e4f6e2c87d8ab7cafa0b269a73", size = 472589, upload-time = "2026-08-28T14:03:59.136Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/f9/8a06bea35ef8daf588f707784c973a7046e0034c8d8cfb08828eeffb8b75/pydantic_core-2.46.5.tar.gz", hash = "sha256:10416c15b8839ecc4ef4d0885da76da6fd0f67333a0eb8aff6d93c4b8f2910fc", size = 472262, upload-time = "2026-08-28T10:01:31.677Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f5/37/5abe39a8372a61d3dc3c1338fc504281c01b32fdb3169cd7187153b56d3e/pydantic_core-2.46.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:b7ca9034437b6022f941f4857459562ee00a560b97e7cce8a0ec5a74fc6766e0", size = 2075885, upload-time = "2026-08-28T09:58:47.856Z" }, + { url = "https://files.pythonhosted.org/packages/21/43/6323b1f8b217780454c61304bcd2b38ae4762f50754414124603ccc90bb2/pydantic_core-2.46.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f332f0e72a5a0400141f830744e141bf9f97917878dbe968669e8a7fefea78ff", size = 1922768, upload-time = "2026-08-28T09:58:49.58Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a3/c05ca796e1197618a774b01e596aeedfefc2f7d8c01ae3054e910b120e8a/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:193375f3548919d3f0b60936ca113ada3e38f264f91b9b8e0508efaad57be931", size = 1951241, upload-time = "2026-08-28T09:58:51.511Z" }, + { url = "https://files.pythonhosted.org/packages/68/32/33bc39ac705c52cffc908e8389f9754fdb208aea5c69cceddf4eb3ce99af/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79bdfa52f843137045b2d081cc05c120ba6665d29b7559c2c47690906f39279f", size = 2031975, upload-time = "2026-08-28T09:58:53.166Z" }, + { url = "https://files.pythonhosted.org/packages/b0/70/2333e885c0f6a67bc105c5916965dac9b57f2718ee20d81d1a06a4ebdc13/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24922243639cbdac66c75fcb6fd6495a9cb52b213d62f9a0d16f0310b1ff8038", size = 2208542, upload-time = "2026-08-28T09:58:55.017Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ea/296debfb4264207bbda5936133892e027c0a58875ad53ebd512fba8ec3a2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c76fe65e607be28c7fd4d56fc3c42b1583aa058ce3408b7ad0fd540171d31f9f", size = 2264692, upload-time = "2026-08-28T09:58:56.767Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f2/9e4de77a6271e07a76d2d58b11c091a979c191ed2939bf80067568b369d2/pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f7b393a8b3da82f5c1fc0751e6d01ac6c55b93c18226a60bdfba4a724efafd1", size = 2066633, upload-time = "2026-08-28T09:58:58.531Z" }, + { url = "https://files.pythonhosted.org/packages/8d/db/f9e9d0c97445987b2084823d5c240de88087338f04fc2cfaa2df186b8049/pydantic_core-2.46.5-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:7ac031912d54f3d83ef3b3eb98dfabc1608802e2202263d25957eeed40b94761", size = 2105235, upload-time = "2026-08-28T09:59:00.421Z" }, + { url = "https://files.pythonhosted.org/packages/07/c5/79169b047b3b2c3e99e04bc76372af9637e0bf6db638274fa927df96369e/pydantic_core-2.46.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:837b396ca3d7b74091ca623f6cbd8351bd42d670a79c2683e79fb089f06a2de5", size = 2157367, upload-time = "2026-08-28T09:59:02.442Z" }, + { url = "https://files.pythonhosted.org/packages/26/b5/ba6057afb7c291bd449f51b867f95aef2072941c4ce4e5c31d6ffd132d3b/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:5ee239d575f80b08eca11f6e20f90c4c695de7825c67eefe6091fbf20dda648e", size = 2158420, upload-time = "2026-08-28T09:59:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/6e/28/2057abecaafdc22912afa819603a51f0a62d40643b7c4871c51721fea9be/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:e80675d75ae2cd14372cb65cad5400d9347a3d3f6c13000183f22dfd027283ed", size = 2309588, upload-time = "2026-08-28T09:59:06.048Z" }, + { url = "https://files.pythonhosted.org/packages/71/9d/881156dc404e27479c4246128d73538464cab4a239bec61995e227644c30/pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c4b71f10dd532fb7a5cbc8f58707779e64f03a258c2bf8bfbaecfcd9970b519", size = 2341866, upload-time = "2026-08-28T09:59:08.539Z" }, + { url = "https://files.pythonhosted.org/packages/5a/38/d66f443a259f84d13babdceae568e572b0ed26da17ca5d0a649ebb110a67/pydantic_core-2.46.5-cp313-cp313-win32.whl", hash = "sha256:97bf8de4d541598c94a59344eeb988a94c08ff76b5723c41f6567ec18c7892ea", size = 1938580, upload-time = "2026-08-28T09:59:10.402Z" }, + { url = "https://files.pythonhosted.org/packages/2c/1e/1d5371213f4cc9a7ed70c0bfcc7911de22311ee99a662a56077d7292d2ac/pydantic_core-2.46.5-cp313-cp313-win_amd64.whl", hash = "sha256:15f4a94963c95accac15b7b657bb177d3ad82bb90b0d0526d9a9b85079925db5", size = 2041980, upload-time = "2026-08-28T09:59:12.396Z" }, + { url = "https://files.pythonhosted.org/packages/5a/48/4222d90b1c67568bace4dec6dca6271449c66de3595d72b6d098f5fde597/pydantic_core-2.46.5-cp313-cp313-win_arm64.whl", hash = "sha256:d22a945598fb91236b4dd793a6e42e4f3dd7740bb5aace5ebd7d4c08d13bb575", size = 1997213, upload-time = "2026-08-28T09:59:14.245Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, +] diff --git a/examples/omniroute-codex-sdk/worker.py b/examples/omniroute-codex-sdk/worker.py index 013b226c0..bb493b8bf 100644 --- a/examples/omniroute-codex-sdk/worker.py +++ b/examples/omniroute-codex-sdk/worker.py @@ -61,7 +61,9 @@ def request_id(value: str) -> str: def positive_seconds(value: str) -> float: seconds = float(value) if not 0 < seconds <= 3600: - raise argparse.ArgumentTypeError("timeout must be greater than zero and at most 3600 seconds") + raise argparse.ArgumentTypeError( + "timeout must be greater than zero and at most 3600 seconds" + ) return seconds @@ -103,7 +105,9 @@ def runtime_config(args: argparse.Namespace) -> CodexConfig: def result_record(result) -> dict: """Retain native snapshots; total is cumulative and last is not a turn sum.""" - kinds = Counter(item.model_dump(mode="json", by_alias=True).get("type") for item in result.items) + kinds = Counter( + item.model_dump(mode="json", by_alias=True).get("type") for item in result.items + ) return { "status": result.status.value, "turn_id": result.id, @@ -112,7 +116,9 @@ def result_record(result) -> dict: "item_counts": dict(kinds), "usage_status": "reported" if result.usage is not None else "unknown", "usage_scope": "native_thread_cumulative" if result.usage is not None else None, - "usage": result.usage.model_dump(mode="json", by_alias=True) if result.usage is not None else None, + "usage": result.usage.model_dump(mode="json", by_alias=True) + if result.usage is not None + else None, } @@ -120,7 +126,9 @@ def emit(value: dict) -> None: print(json.dumps(value, ensure_ascii=False, separators=(",", ":")), flush=True) -async def run_worker(args: argparse.Namespace, prompt: str, *, sdk_factory=AsyncCodex, on_event=emit) -> dict: +async def run_worker( + args: argparse.Namespace, prompt: str, *, sdk_factory=AsyncCodex, on_event=emit +) -> dict: """Use native start/resume/turn/interrupt/close, with one overall deadline.""" codex = sdk_factory(config=runtime_config(args)) turn = None @@ -179,7 +187,10 @@ async def run_worker(args: argparse.Namespace, prompt: str, *, sdk_factory=Async json.dump(native, output, ensure_ascii=False, indent=2) output.write("\n") except (TimeoutError, asyncio.CancelledError) as exc: - record.update(status="deadline_exceeded" if isinstance(exc, TimeoutError) else "cancelled", phase=phase) + record.update( + status="deadline_exceeded" if isinstance(exc, TimeoutError) else "cancelled", + phase=phase, + ) if turn is not None: try: await asyncio.wait_for(turn.interrupt(), CLEANUP_TIMEOUT) @@ -206,17 +217,46 @@ def parse_args(argv=None) -> argparse.Namespace: parser.add_argument("--workspace", type=Path, default=Path.cwd()) parser.add_argument("--prompt", default="-", help="one bounded task, or - to read stdin") parser.add_argument("--resume", help="native thread id from an earlier invocation") - parser.add_argument("--model", default=DEFAULT_MODEL, help="explicit native/gateway model id; default Sol/max route") + parser.add_argument( + "--model", + default=DEFAULT_MODEL, + help="explicit native/gateway model id; default Sol/max route", + ) parser.add_argument("--base-url", type=gateway_url, default=DEFAULT_BASE_URL) parser.add_argument("--request-id", type=request_id, default=uuid.uuid4().hex) parser.add_argument("--timeout", type=positive_seconds, default=300.0) - parser.add_argument("--sandbox", choices=[Sandbox.read_only.value, Sandbox.workspace_write.value], default=Sandbox.workspace_write.value) - parser.add_argument("--approval-mode", choices=[mode.value for mode in ApprovalMode], default=ApprovalMode.deny_all.value) - parser.add_argument("--codex-bin", type=Path, help="explicit native 0.159.2 binary; defaults to the pinned SDK bundle") - parser.add_argument("--codex-home", type=Path, help="optional private worker config/state; inherited when omitted") - parser.add_argument("--api-key-env", help="optional gateway credential variable name; no credential value is accepted") - parser.add_argument("--no-provider-retries", action="store_true", help="disarm native request/stream retries for a measured attempt") - parser.add_argument("--native-result", type=Path, help="retain full native items in a new private 0600 file") + parser.add_argument( + "--sandbox", + choices=[Sandbox.read_only.value, Sandbox.workspace_write.value], + default=Sandbox.workspace_write.value, + ) + parser.add_argument( + "--approval-mode", + choices=[mode.value for mode in ApprovalMode], + default=ApprovalMode.deny_all.value, + ) + parser.add_argument( + "--codex-bin", + type=Path, + help="explicit native 0.159.2 binary; defaults to the pinned SDK bundle", + ) + parser.add_argument( + "--codex-home", + type=Path, + help="optional private worker config/state; inherited when omitted", + ) + parser.add_argument( + "--api-key-env", + help="optional gateway credential variable name; no credential value is accepted", + ) + parser.add_argument( + "--no-provider-retries", + action="store_true", + help="disarm native request/stream retries for a measured attempt", + ) + parser.add_argument( + "--native-result", type=Path, help="retain full native items in a new private 0600 file" + ) args = parser.parse_args(argv) if not args.workspace.is_dir(): parser.error("workspace must be an existing directory") @@ -235,7 +275,14 @@ def main() -> int: try: result = asyncio.run(run_worker(args, prompt)) except KeyboardInterrupt: - emit({"event": "cancelled", "request_id": args.request_id, "usage_status": "unknown", "usage": None}) + emit( + { + "event": "cancelled", + "request_id": args.request_id, + "usage_status": "unknown", + "usage": None, + } + ) return 130 emit({"event": "result", **result}) return 0 if result["status"] == "completed" else 2 From 5b5758269898fa7e1dd0bf145ff25d371b856560 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 11:59:40 -0400 Subject: [PATCH 05/14] docs(foundation): specify native Claude runtime worker invocation --- examples/omniroute-codex-sdk/README.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/examples/omniroute-codex-sdk/README.md b/examples/omniroute-codex-sdk/README.md index 8f721bd54..8afe1e6ee 100644 --- a/examples/omniroute-codex-sdk/README.md +++ b/examples/omniroute-codex-sdk/README.md @@ -6,19 +6,32 @@ the primary worker and an invocation-scoped OmniRoute Responses provider. The existing Codex integration remains the incumbent; this example does not select a winner in the separate SDK comparison. -## Run one bounded task +## Call from a native Claude coordinator The PEP 723 scripts and adjacent locks pin `openai-codex==0.159.2`, including -its matching native CLI. Use the existing selected gateway and a task worktree. -Run from the repository root: +its matching native CLI. In the native Claude session, use its `Bash` tool to run +the following command from the repository root. `WORKER_PROJECT` is the owned +task worktree with the selected project `.agents/skills`; `PRIVATE_WORKER_HOME` +is an existing independent private Codex configuration/state directory prepared +through the selected adoption recipe. `WORKER_TASK` contains the bounded task +and its artifact/test contract. Pass only that task, not the coordinator's whole +conversation. `PRIVATE_NATIVE_RESULT` names a new private artifact path. ```sh rtk uv run --locked --script examples/omniroute-codex-sdk/worker.py \ --workspace "$WORKER_PROJECT" \ --codex-home "$PRIVATE_WORKER_HOME" \ - --prompt - + --prompt "$WORKER_TASK" \ + --native-result "$PRIVATE_NATIVE_RESULT" ``` +This subprocess contract scopes the provider to the SDK worker; native Claude +and Codex coordinator sessions retain their account routes and configuration. +Source: [Claude native Bash/tool usage](https://code.claude.com/docs/en/overview), +the official SDK launch contract and the provider sources below. A source-backed +caller recipe is distinct from observing an actual Claude `Bash` invocation; +retain that native invocation before claiming Claude-side execution acceptance. + The default endpoint is the selected loopback gateway at port 20128. An owned reverse observer can be supplied with `--base-url`; the worker never changes gateway compression engines or native coordinator configuration. The default From 6a06cfdae659e47b02849ea918dbba1ed36455ee Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 12:24:41 -0400 Subject: [PATCH 06/14] feat(foundation): qualify scoped OmniRoute runtime worker lifecycle --- .../skills/omniroute-runtime-worker/SKILL.md | 42 ++ .../omniroute-runtime-workers/experiment.json | 699 ++++++++++++++++++ .../2026-09-30-omniroute-runtime-workers.md | 115 +++ .../omniroute-runtime-workers-20260930.json | 418 +++++++++++ manifests/evidence.json | 122 +++ tools/runtime-worker-evidence/README.md | 29 + tools/runtime-worker-evidence/checks.json | 81 ++ .../gateway_observer.py | 139 ++++ .../test_gateway_observer.py | 83 +++ 9 files changed, 1728 insertions(+) create mode 100644 .claude/skills/omniroute-runtime-worker/SKILL.md create mode 100644 blueprints/convergence-practice/omniroute-runtime-workers/experiment.json create mode 100644 docs/decisions/2026-09-30-omniroute-runtime-workers.md create mode 100644 evidence/receipts/omniroute-runtime-workers-20260930.json create mode 100644 tools/runtime-worker-evidence/README.md create mode 100644 tools/runtime-worker-evidence/checks.json create mode 100644 tools/runtime-worker-evidence/gateway_observer.py create mode 100644 tools/runtime-worker-evidence/test_gateway_observer.py diff --git a/.claude/skills/omniroute-runtime-worker/SKILL.md b/.claude/skills/omniroute-runtime-worker/SKILL.md new file mode 100644 index 000000000..bcd21d94d --- /dev/null +++ b/.claude/skills/omniroute-runtime-worker/SKILL.md @@ -0,0 +1,42 @@ +--- +name: omniroute-runtime-worker +description: Delegate a bounded foundation engineering task from Claude to the native Codex SDK worker through the selected OmniRoute gateway. +--- + +Read `examples/omniroute-codex-sdk/README.md` for invocation and lifecycle details. +Use this project's `examples/omniroute-codex-sdk/worker.py` through Claude's native +Bash tool. The primary route is `cx/gpt-6.1-sol-max`, with native Max effort. +The coordinator retains its native Claude account and model route. + +Give a writing worker its own worktree, bounded file ownership, an executable +acceptance condition and an existing private Codex home. Tell it other workers +are present and that it must preserve their edits. Feed the task on stdin: + +```sh +rtk uv run --locked --script examples/omniroute-codex-sdk/worker.py \ + --workspace "$WORKER_PROJECT" \ + --codex-home "$PRIVATE_WORKER_HOME" \ + --timeout 300 \ + --prompt - +``` + +Use the selected gateway's native Responses lane at loopback port 20128. Keep +native caches, tools and project skill discovery intact; load only task-relevant +skill bodies. Install selected skills through the existing runtime-worker skill +recipe, rather than importing the entire catalog into the task prompt. Optional +MCP services require their own configuration and acceptance. + +Keep returned thread IDs private and use `--resume` for continuation. The latest +thread usage snapshot includes previous turns; count it once. A deadline invokes +native interruption and child cleanup; remote termination and unknown provider +usage remain unverified. Do not automatically replay a failed writing task. + +Use explicit `--model cx/gpt-6-astra-max` for consequential architecture, +conflicting primary evidence, or a failure unresolved after one bounded Sol +repair. Record that trigger and the acceptance result. The separate Claude SDK +bridge remains a trial after its gateway errors; it is not the primary worker. + +Sources: [Claude native project skills](https://code.claude.com/docs/en/skills) +and [official Codex SDK, rust-v0.159.2](https://github.com/openai/codex/tree/ff6aec96948b70d94983af2641a6b67c94faeff5/sdk/python). +Functional scope and retained failures are recorded in +`docs/decisions/2026-09-30-omniroute-runtime-workers.md`. diff --git a/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json b/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json new file mode 100644 index 000000000..e2dea75cb --- /dev/null +++ b/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json @@ -0,0 +1,699 @@ +{ + "schema_version": 1, + "kind": "convergence_experiment", + "status": "observed", + "lane": "native-agent-engineering", + "task_and_failure": "Provide Claude's foundation coordinator with high-quality native OmniRoute runtime workers and task-relevant skills. Qualify the retained Codex SDK lifecycle; hold the Claude Devin bridge after one source-backed repair still fails.", + "primary_sources_and_pins": [ + { + "url": "https://github.com/openai/codex/tree/ff6aec96948b70d94983af2641a6b67c94faeff5/sdk/python", + "revision": "ff6aec96948b70d94983af2641a6b67c94faeff5" + }, + { + "url": "https://github.com/anthropics/claude-agent-sdk-python/tree/f2204bb956bab02907aaf3cb88eb9dead28eaa35", + "revision": "f2204bb956bab02907aaf3cb88eb9dead28eaa35" + }, + { + "url": "https://github.com/diegosouzapw/OmniRoute/tree/c1e30b7676975feb298b49eff6ff58923c04b89e/tests/fixtures/devin-bridge/e2e-workspace", + "revision": "c1e30b7676975feb298b49eff6ff58923c04b89e" + }, + { + "url": "https://github.com/diegosouzapw/OmniRoute/tree/2f42a9ac19d1a247ec9ce5473b790843724b3061/open-sse/executors/devin-agentic", + "revision": "2f42a9ac19d1a247ec9ce5473b790843724b3061" + }, + { + "url": "https://github.com/vercel-labs/skills/tree/7407f3893ad4dceab546ac002c3ef806e4000c73", + "revision": "7407f3893ad4dceab546ac002c3ef806e4000c73" + }, + { + "url": "https://github.com/mitmproxy/mitmproxy/tree/6c09d56e4c29a92f5ad01b03199977584b8ea14f", + "revision": "6c09d56e4c29a92f5ad01b03199977584b8ea14f" + } + ], + "discovery_provenance": [ + "Installed client/SDK command and version inspection, official tagged source and release records, maintained skill discovery and native Vercel installer.", + "Native Claude ListAgents/SendMessage owner contacts and independently checked public PR535/524 leads.", + "Astra/Max original-source review for consequential translated bridge architecture and failure unresolved after one bounded Sol repair." + ], + "license_and_compatibility": "Use maintained Codex Apache-2.0 SDK/native runtime and licensed native Claude SDK/client. OmniRoute fixture is reused from its pinned published source. Loopback worker configuration is child-only; no global route, auth store, compression engine or interactive model changes.", + "baseline_and_candidate": { + "baseline": "Retained Codex SDK incumbent and native Claude interactive coordination; separate three-arm SDK comparison unresolved.", + "candidate": "Bounded Sol-Max Codex SDK coding worker on the selected OmniRoute Responses lane, plus native Claude on-demand dispatch skill; Claude SDK translated bridge retained as failed trial." + }, + "frozen_inputs": { + "base_revision": "5cfa2400e3ebb4aefb8419135345c1fa92b05409", + "tasks": [ + "skill-install", + "skill-check", + "code-fix", + "resume", + "invalid-resume", + "interrupt", + "fresh-recovery", + "claude-bridge", + "owner-cooperation", + "analytical-review", + "bare-auth", + "fixture-negative", + "fixture-positive" + ], + "roles": [ + "installer", + "sol-worker", + "claude-worker", + "claude-peer", + "astra-judge", + "oracle" + ], + "sources": [ + { + "path": "examples/omniroute-codex-sdk/worker.py", + "sha256": "8dfa1799dc2ce034548eb2581befe61bef480728cc541a451e960bb48decc651" + }, + { + "path": "examples/omniroute-codex-sdk/worker.py.lock", + "sha256": "15e5e7cfeec11ac86d8f081742c726c0d70326b480894a81e5cc76a7d9225c44" + } + ], + "inputs": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + }, + { + "path": ".claude/skills/omniroute-runtime-worker/SKILL.md", + "sha256": "857a00f0c3f4088a20662f32f422b30c4697d0c267c0db1f9dbb95dfcbe39ce5" + } + ], + "evaluation": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + }, + { + "path": "examples/omniroute-codex-sdk/test_worker.py", + "sha256": "ea30d5bd0568f1e179e6460647ef61f2ca1ca025bda574f5f35a315eeee2ae2a" + } + ] + }, + "predeclared_metrics": { + "quality_rule": "Before provider trials require task skill read, only intended fixture edit, unchanged oracle pass, native resume, interruption and fresh recovery. This functional record is not a preregistered comparative SDK winner trial. Exact live source commits and AST-equivalent final formatting are retained.", + "usage_rule": "Preserve native cumulative thread snapshots; count latest snapshot once or difference comparable snapshots. Observation sol-resume uses the incremental difference from sol-fix, rather than adding cumulative totals. Cache/read and reasoning are subsets; failures and incomplete provider coverage remain unknown." + }, + "runtime_and_platform": { + "platform": "Linux x86_64; Python 3.14.7 for worker invocation; unchanged Claude SDK suite separately Python 3.13.15.", + "tools": [ + { + "name": "Codex Python SDK and native CLI", + "version": "0.159.2" + }, + { + "name": "Claude Agent SDK", + "version": "0.2.162 / bundled CLI2.1.285" + }, + { + "name": "OmniRoute", + "version": "3.8.51, running-base revision plus owned patches" + }, + { + "name": "Vercel skills", + "version": "1.7.0" + }, + { + "name": "mitmproxy", + "version": "12.2.3" + } + ], + "isolation": "Separate writing worktrees and bounded ownership, owned project and private worker home, separate per-invocation SDK child, dedicated loopback observer. Native interactive sessions and other owners' services/state preserved." + }, + "commands": [ + "rtk python3 tools/adoption/install_skills.py --manifest blueprints/runtime-workers/skills/manifest.json --project-dir --agent claude-code --skills-bin --json", + "Same supported skill installer with --check-only", + "rtk uv run --locked --script examples/omniroute-codex-sdk/worker.py --workspace --codex-home --base-url /v1 --prompt - --no-provider-retries --native-result ", + "Same native worker with --resume --sandbox read-only and new private result", + "Same native worker with invalid retained thread, --sandbox read-only", + "Same native worker with --timeout 3 --sandbox read-only", + "Same native worker with new thread --sandbox read-only", + "rtk uv run --locked --script examples/claude-runtime-sdk/worker.py --cwd --gateway --model dva/claude-opus-5-max --skill bridge-proof --setting-source project --permission-mode dontAsk --allow-tool Read --max-turns 6 --timeout 90 --result-output ", + "Same Claude SDK trial after source-backed child authentication repair", + "Native Claude background Opus 5.5/Max ListAgents/SendMessage cooperation; stop only owned session after no final packet", + "rtk proxy timeout --signal=TERM --kill-after=5s 240s claude -p --model claude-opus-5-5 --effort max --tools '' --strict-mcp-config --no-session-persistence --output-format json < ", + "Native bare-mode analytical review negative control; no native authentication loading", + "rtk npm test (independent unchanged upstream fixture before and after the worker)" + ], + "observations": [ + { + "id": "skills-install", + "task": "skill-install", + "role": "installer", + "condition": "candidate", + "attempt": 1, + "command_index": 0, + "evidence_class": "native_cli_execution", + "scope": "Install selected 136 skills into owned project", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": 0, + "cache_creation": 0, + "cache_read": 0, + "output": 0, + "reasoning_in_output": 0, + "total": 0, + "native_retries": 0 + } + }, + { + "id": "skills-check", + "task": "skill-check", + "role": "installer", + "condition": "candidate", + "attempt": 1, + "command_index": 1, + "evidence_class": "native_cli_execution", + "scope": "Check selected 136 skills in owned project", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": 0, + "cache_creation": 0, + "cache_read": 0, + "output": 0, + "reasoning_in_output": 0, + "total": 0, + "native_retries": 0 + } + }, + { + "id": "sol-preflight", + "task": "code-fix", + "role": "sol-worker", + "condition": "candidate", + "attempt": 1, + "command_index": 2, + "evidence_class": "native_cli_execution", + "scope": "Native Sol-Max SDK coding worker on the selected OmniRoute Responses lane", + "status": "failed", + "exit_code": 2, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "sol-fix", + "task": "code-fix", + "role": "sol-worker", + "condition": "candidate", + "attempt": 2, + "command_index": 2, + "evidence_class": "model_task_execution", + "scope": "Native Sol-Max SDK coding worker on the selected OmniRoute Responses lane", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": 44645, + "cache_creation": 0, + "cache_read": 91904, + "output": 2818, + "reasoning_in_output": 1480, + "total": 139367, + "native_retries": 0 + } + }, + { + "id": "sol-resume", + "task": "resume", + "role": "sol-worker", + "condition": "candidate", + "attempt": 1, + "command_index": 3, + "evidence_class": "model_task_execution", + "scope": "Native Sol-Max SDK coding worker on the selected OmniRoute Responses lane", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": 8129, + "cache_creation": 0, + "cache_read": 49792, + "output": 529, + "reasoning_in_output": 165, + "total": 58450, + "native_retries": 0 + } + }, + { + "id": "sol-invalid-resume", + "task": "invalid-resume", + "role": "sol-worker", + "condition": "candidate", + "attempt": 1, + "command_index": 4, + "evidence_class": "recovery_execution", + "scope": "Native Sol-Max SDK coding worker on the selected OmniRoute Responses lane", + "status": "failed", + "exit_code": 2, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "sol-deadline", + "task": "interrupt", + "role": "sol-worker", + "condition": "candidate", + "attempt": 1, + "command_index": 5, + "evidence_class": "recovery_execution", + "scope": "Native Sol-Max SDK coding worker on the selected OmniRoute Responses lane", + "status": "failed", + "exit_code": 2, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "sol-recovery", + "task": "fresh-recovery", + "role": "sol-worker", + "condition": "candidate", + "attempt": 1, + "command_index": 6, + "evidence_class": "recovery_execution", + "scope": "Native Sol-Max SDK coding worker on the selected OmniRoute Responses lane", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": 596, + "cache_creation": 0, + "cache_read": 30208, + "output": 123, + "reasoning_in_output": 42, + "total": 30927, + "native_retries": 0 + } + }, + { + "id": "claude-prototype", + "task": "claude-bridge", + "role": "claude-worker", + "condition": "candidate", + "attempt": 1, + "command_index": 7, + "evidence_class": "model_task_execution", + "scope": "Claude SDK Devin bridge native tool acceptance", + "status": "failed", + "exit_code": 1, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "claude-auth-repair", + "task": "claude-bridge", + "role": "claude-worker", + "condition": "candidate", + "attempt": 2, + "command_index": 8, + "evidence_class": "model_task_execution", + "scope": "Claude SDK Devin bridge native tool acceptance", + "status": "failed", + "exit_code": 1, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "claude-cooperation", + "task": "owner-cooperation", + "role": "claude-peer", + "condition": "candidate", + "attempt": 1, + "command_index": 9, + "evidence_class": "model_task_execution", + "scope": "Native peer final cooperation packet", + "status": "failed", + "exit_code": null, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "claude-review-timeout", + "task": "analytical-review", + "role": "claude-peer", + "condition": "candidate", + "attempt": 1, + "command_index": 10, + "evidence_class": "model_task_execution", + "scope": "Bounded native analytical review approval", + "status": "failed", + "exit_code": 124, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "claude-bare-auth", + "task": "bare-auth", + "role": "claude-peer", + "condition": "candidate", + "attempt": 1, + "command_index": 11, + "evidence_class": "native_cli_execution", + "scope": "Bare-mode authentication negative control", + "status": "failed", + "exit_code": 1, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "independent-negative", + "task": "fixture-negative", + "role": "oracle", + "condition": "candidate", + "attempt": 1, + "command_index": 12, + "evidence_class": "native_cli_execution", + "scope": "Unchanged upstream arithmetic fixture", + "status": "failed", + "exit_code": 1, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": 0, + "cache_creation": 0, + "cache_read": 0, + "output": 0, + "reasoning_in_output": 0, + "total": 0, + "native_retries": 0 + } + }, + { + "id": "independent-positive", + "task": "fixture-positive", + "role": "oracle", + "condition": "candidate", + "attempt": 1, + "command_index": 12, + "evidence_class": "native_cli_execution", + "scope": "Unchanged upstream arithmetic fixture", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + ], + "usage": { + "uncached_input": 0, + "cache_creation": 0, + "cache_read": 0, + "output": 0, + "reasoning_in_output": 0, + "total": 0, + "native_retries": 0 + } + } + ], + "failures_and_skips": [ + { + "run_id": "sol-preflight", + "reason": "Private Codex home did not exist. Native setup failed before inference; created owned 0700 directory, no global state change." + }, + { + "run_id": "sol-invalid-resume", + "reason": "Expected discriminating InvalidRequestError before inference; cleanup closed; unknown usage retained." + }, + { + "run_id": "sol-deadline", + "reason": "Expected three-second deadline during turn; interrupt requested and cleanup closed. Native usage unknown; not proof of provider termination." + }, + { + "run_id": "claude-prototype", + "reason": "90-second native deadline with zero tool calls; prototype did not carry documented keyless gateway auth sentinel. Overall provider usage unknown." + }, + { + "run_id": "claude-auth-repair", + "reason": "Source-backed child auth repair still returned gateway HTTP500 and 90-second deadline; zero tool calls, no successful provider usage. No third retry." + }, + { + "run_id": "claude-cooperation", + "reason": "Native owner contacts made, but no final packet received. Stopped only owned session; partial/cooperation usage unknown." + }, + { + "run_id": "claude-review-timeout", + "reason": "240-second analytical native review timed out with empty final result; no approval; usage unknown." + }, + { + "run_id": "claude-bare-auth", + "reason": "Bare-mode review returned authentication_failed; bare skips native authentication loading, so no account-absence claim." + }, + { + "run_id": "independent-negative", + "reason": "Deliberate before-fix negative control: upstream add incorrectly subtracts. Original test exit1; retained without changing oracle." + } + ], + "limitations": [ + "Draft reproduction text used incorrect Claude wrapper flag names. Both installed runner --help commands were checked before publication; the text now uses --cwd/--gateway/--skill/--setting-source, with Max effort configured natively by the runner. Actual attempted calls and results did not change.", + "The first authored record validation failed because administrative task and role IDs were omitted from frozen_inputs. Those metadata declarations were corrected; no provider run or result changed.", + "One arithmetic fixture and lifecycle acceptance; no universal SDK or model quality ranking.", + "Actual provider trials invoked the SDK from root, rather than through a Claude coordinator. Native project dispatch skill is supplied and structurally checked; its coordinator invocation remains unmeasured.", + "Native Codex SDK remains the incumbent. The separate frozen three-arm SDK gate remains unresolved.", + "Native gateway requested/returned model labels are not backend attestation.", + "All 136 skills are available in the owned project, with two bodies exercised; full role coverage and optional service acceptance remain incomplete.", + "Native Codex repeated in-process fixtures emit stdout/stderr ResourceWarnings; standalone per-invocation child exit is qualified separately.", + "Complete provider usage, spending, remote cancellation and token savings remain unknown.", + "Public record is sanitized selected actual return fields and independent observations; original private returned artifacts remain outside the checkout.", + "Source/evaluation artifacts pin the final formatting-equivalent implementation; exact pre-format live worker bytes are retained in native commits named in the receipt.", + "The 136-skill native installation and check are separate from per-task quality. Upstream source suites, authored local fixtures and actual provider execution remain separate." + ], + "decision_and_scope": { + "decision": "adopt_within_scope", + "scope": "Native Sol-Max SDK coding worker on the selected OmniRoute Responses lane", + "qualification_run_ids": [ + "sol-fix", + "sol-resume", + "sol-recovery" + ] + }, + "rollback": "Stop the owned invocation/observer and use the retained native coordinator/runtime path. Keep recoverable private thread state for resume; no shared gateway or account rollback is needed because none was changed.", + "next_decision_changing_test": "Observe an actual native Claude coordinator invocation of the supplied project skill. Separately, a repaired Claude bridge must pass native skill/tool/edit/oracle/resume/cancel/recovery and truthful usage acceptance before promotion. Preserve the existing frozen three-arm SDK gate for any SDK-winner change.", + "usage_assessment": { + "claim": "none", + "coverage": "partial", + "expected_run_ids": [ + "skills-install", + "skills-check", + "sol-preflight", + "sol-fix", + "sol-resume", + "sol-invalid-resume", + "sol-deadline", + "sol-recovery", + "claude-prototype", + "claude-auth-repair", + "claude-cooperation", + "claude-review-timeout", + "claude-bare-auth", + "independent-negative", + "independent-positive" + ], + "coverage_artifact": { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" + } + } +} diff --git a/docs/decisions/2026-09-30-omniroute-runtime-workers.md b/docs/decisions/2026-09-30-omniroute-runtime-workers.md new file mode 100644 index 000000000..889902238 --- /dev/null +++ b/docs/decisions/2026-09-30-omniroute-runtime-workers.md @@ -0,0 +1,115 @@ +# OmniRoute runtime workers called from native Claude + +Use the retained official Codex SDK for the primary foundation coding worker: +`cx/gpt-6.1-sol-max` through the selected OmniRoute Responses lane, with native +Max effort. Native interactive Claude and Codex keep their existing accounts and +routes. The [project Claude skill](../../.claude/skills/omniroute-runtime-worker/SKILL.md) +dispatches the [bounded worker](../../examples/omniroute-codex-sdk/README.md) +through Claude's native Bash tool, with a separate worktree and private worker +home. Configuration remains scoped to the child process. The existing frozen +three-arm SDK comparison remains unresolved; this is functional qualification of +the retained implementation for one application role. + +## Sources and selection + +The maintained [Codex SDK at rust-v0.159.2](https://github.com/openai/codex/tree/ff6aec96948b70d94983af2641a6b67c94faeff5/sdk/python) +supplies the native start/resume/turn/interrupt/close lifecycle. Published SDK and +bundled CLI versions are 0.159.2, pinned by native uv script locks. Sol model +metadata survives the single gateway namespace through +[native model matching](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/models-manager/src/manager.rs#L763). +The [Claude project Skills format](https://code.claude.com/docs/en/skills) supplies +the coordinator's on-demand entry point; it adds no outer orchestration runtime. + +The alternative [Claude Agent SDK v0.2.162](https://github.com/anthropics/claude-agent-sdk-python/tree/f2204bb956bab02907aaf3cb88eb9dead28eaa35) +is implemented in [a separate trial](../../examples/claude-runtime-sdk/README.md), +with explicit native prompt preset, tools, settings, skills and lifecycle. Its +advertised `dva/claude-opus-5-max` route uses OmniRoute's translated Devin bridge. +The [running-base serializer](https://github.com/diegosouzapw/OmniRoute/blob/2f42a9ac19d1a247ec9ce5473b790843724b3061/open-sse/executors/devin-agentic/serializer.ts), +[tool parser](https://github.com/diegosouzapw/OmniRoute/blob/2f42a9ac19d1a247ec9ce5473b790843724b3061/open-sse/executors/devin-agentic/toolParser.ts) +and [usage estimator](https://github.com/diegosouzapw/OmniRoute/blob/2f42a9ac19d1a247ec9ce5473b790843724b3061/open-sse/executors/devin-agentic/types.ts) +establish translation, finite tool-result truncation, restricted envelopes and +estimated usage. Advertised model labels do not attest backend identity. The +[official Claude gateway contract](https://code.claude.com/docs/en/llm-gateway) +requires Claude models; it does not qualify this translation or non-Claude model +substitution inside the Claude harness. + +The running OmniRoute 3.8.51 base and its owned patches differ from the published +3.8.51 tag. Port 20128's existing compression-off lane was preserved. No gateway +engine, global authentication setting or interactive model route was changed. + +## Actual acceptance and limits + +The [sanitized receipt](../../evidence/receipts/omniroute-runtime-workers-20260930.json) +retains selected actual native returns, failed attempts and independent +observations. A Sol/Max worker read two task-relevant skill bodies, repaired only +`math.js` in the upstream OmniRoute arithmetic fixture, and passed its unchanged +test. Independent execution observed the defect before the task and success +after it. Native resume retained the same thread and passed. An invalid resume +failed before inference; a three-second deadline requested native interruption; +a fresh thread then passed. The cancellation result is in its private log, not +an original-result JSON file. Remote termination remains unverified. + +The gateway observer confirms Max effort and native ResponsesLite tool carriage +under `input[].type=additional_tools`. The first authored oracle incorrectly +expected top-level `tools`; original tagged source corrected that failed oracle. +Resume preserved the native cache key and stable tool prefix. Six authored +SDK/native-CLI transport tests and five observer tests passed. Their local +synthetic evidence remains distinct from actual provider execution. The prior +unchanged Codex source suite retains one formatter-driver failure; no complete +Codex upstream-suite passing claim is made. Repeated calls in one Python process +also expose native SDK pipe ResourceWarnings. Standalone child exit is checked; +a long-running in-process pool is unqualified. + +The supported pinned skill installer installed 136 catalog skills in the owned +project, and its independent check reported 136 OK. Native task execution read +`using-superpowers` plus the additional upstream `bridge-proof` fixture skill. +The latter was an explicit Claude-path read, not Codex implicit discovery. Keep +metadata discovery, actual body loading and task outcomes separate. Fifteen role +gaps, three capability gaps, the remaining skills and optional MCP integrations +retain their existing qualification limits. Follow the existing native skill +lifecycle; do not preload every body or start optional services by default. + +Both Claude gateway attempts timed out with zero tool calls. The observed +Messages requests returned HTTP 500. One bounded Sol repair adopted the +[native launcher child environment](https://github.com/diegosouzapw/OmniRoute/blob/2f42a9ac19d1a247ec9ce5473b790843724b3061/bin/cli/commands/launch.mjs), +including keyless gateway authentication and discovery. The repaired attempt +still failed, so the bridge remains unqualified. This does not establish the +cause of the first timeout. Separately, the unchanged Claude SDK suite passed +1,587 tests with six skips; 24 authored local checks passed. Neither result +overrides failed provider acceptance. + +## Judgment, cooperation and token accounting + +Consequential bridge architecture and failure after one bounded Sol repair +triggered an Astra/Max original-source and owned-artifact audit. Its acceptance +was limited to the demonstrated Codex SDK lifecycle; it rejected promotion of +the failed Claude bridge. Explicit task models remain explicit. Astra is an +explicit judgment stage, rather than a silent retry or default for every worker. + +Native Opus 5.5/Max contacted the live Claude/default owners through supported +ListAgents/SendMessage. The runtime owner received the +[scope handoff](https://github.com/seathatflowsinourveins/native-agent-stack/pull/535#issuecomment-5913868401). +The [Claude Pi peer's trial](https://github.com/seathatflowsinourveins/native-agent-stack/pull/524) +remains conditional: its small fixtures showed substantial token-stack overhead, +so extra tools are selected by task rather than enabled indiscriminately. The +owned native cooperation session produced no final packet and was stopped. A +subsequent analytical review timed out at 240 seconds without approval; usage is +unknown. Its earlier bare-mode authentication failure does not establish a +missing native account. No peer approval is claimed from these attempts. + +Count the primary thread's latest resumed snapshot once: 197,817 native tokens. +The separate successful recovery thread reports 30,927. Their combined 228,744 +matches independently captured completed-response usage. Cached input and +reasoning output are subsets. Interrupted, failed and preparation usage, +complete provider billing and overall cost remain unknown. No token-savings or +universal quality claim follows from cache reuse. The scoped +[convergence record](../../blueprints/convergence-practice/omniroute-runtime-workers/experiment.json) +checks declared consistency, not truth or comparative superiority. + +Actual provider acceptance invoked the SDK directly from the implementing +coordinator. The supplied Claude dispatch skill is structurally validated; a +native Claude coordinator invoking it remains a distinct unmeasured acceptance +step. Preserve the native sessions, existing SDK comparison gate and live +owner's shared files. Future bridge promotion requires successful native tools, +skills, resume, cancellation/recovery and truthful usage on the selected route; +an advertised model list or unchanged SDK test suite is insufficient. diff --git a/evidence/receipts/omniroute-runtime-workers-20260930.json b/evidence/receipts/omniroute-runtime-workers-20260930.json new file mode 100644 index 000000000..afe6e307b --- /dev/null +++ b/evidence/receipts/omniroute-runtime-workers-20260930.json @@ -0,0 +1,418 @@ +{ + "schema_version": 1, + "id": "omniroute-runtime-workers-20260930", + "kind": "native_model_e2e", + "component_ids": ["codex", "claude-code", "omniroute"], + "claim": "The retained official Codex SDK Sol-Max worker passed one upstream coding fixture, native resume and fresh recovery through the selected OmniRoute Responses lane. Interrupted usage and Claude bridge qualification remain unknown/failed.", + "recorded_at": "2026-09-30T16:01:17Z", + "lane": "foundation", + "decision": "Accept retained Codex SDK / Sol-Max for the demonstrated coding lifecycle; Claude SDK bridge remains unqualified.", + "source_pins": { + "codex": { + "repository": "https://github.com/openai/codex", + "revision": "ff6aec96948b70d94983af2641a6b67c94faeff5", + "tag": "rust-v0.159.2", + "sdk": "openai-codex==0.159.2", + "native_cli": "0.159.2", + "executed_worker_sha256": "aa960eca54f3cb098d74deb63673f6ecf4bcf747ef030b16ee00e4a093c40763", + "executed_source_commit": "3c51e33eca745828912c9948f4c8d127fe3ef9b0", + "script_lock_sha256": "15e5e7cfeec11ac86d8f081742c726c0d70326b480894a81e5cc76a7d9225c44", + "formatted_worker_sha256": "8dfa1799dc2ce034548eb2581befe61bef480728cc541a451e960bb48decc651", + "ast_identical": true + }, + "claude": { + "repository": "https://github.com/anthropics/claude-agent-sdk-python", + "revision": "f2204bb956bab02907aaf3cb88eb9dead28eaa35", + "tag": "v0.2.162", + "sdk": "claude-agent-sdk==0.2.162", + "bundled_cli": "2.1.285", + "executed_worker_sha256": "85deb0e4dc85d5f53d93c22dd988028dcb9f0579300c6daa000ec3bef4a757fc", + "executed_source_commit": "e7e5055c85fbf045c4c442da5e43c881b9c31516", + "formatted_worker_sha256": "92b6077da5f659a9798d61433b73920903dd2637dd4b4ee914e42995d111abf9", + "ast_identical": true + }, + "omniroute": { + "repository": "https://github.com/diegosouzapw/OmniRoute", + "published_version": "3.8.51", + "published_tag_revision": "c1e30b7676975feb298b49eff6ff58923c04b89e", + "running_base_revision": "2f42a9ac19d1a247ec9ce5473b790843724b3061", + "running_owned_patches": [ + "PR13788 affinity2", + "PR15167" + ], + "published_and_running_builds_identical": false, + "selected_gateway_port": 20128, + "compression_enabled": false + }, + "skills": { + "repository": "https://github.com/vercel-labs/skills", + "version": "1.7.0", + "revision": "7407f3893ad4dceab546ac002c3ef806e4000c73", + "manifest_sha256": "6b92a9bd8c91f75e2eac03e60372cb84b6d21d5fce01b2e1a8e2441e6fe74a3f" + }, + "observer": { + "repository": "https://github.com/mitmproxy/mitmproxy", + "version": "12.2.3", + "revision": "6c09d56e4c29a92f5ad01b03199977584b8ea14f", + "integration_sha256": "d4569ed6efef53015eb1619bf5591f91530476896fd6e18f4c2ba44ec07a6f97", + "stream_chunks_returned_unchanged": true, + "capture_scope": "Dedicated owned loopback worker traffic; allowlisted metadata only" + } + }, + "fixture": { + "source": "https://github.com/diegosouzapw/OmniRoute/tree/c1e30b7676975feb298b49eff6ff58923c04b89e/tests/fixtures/devin-bridge/e2e-workspace", + "scope": "One upstream arithmetic fixture; test and package files unchanged.", + "before_sha256": { + "math": "75cfacb7faac086c50b23ac4b29a709eb8680999e6756f620ca76d42aba07cab", + "test": "0a60a61022b4d9333882981dda4d09faf41cc36fd2e9406921fdf6e77b8821de", + "package": "7fa8fd86ba4b048bc7395cece337513c65936af275348074eadb443614b387d6" + }, + "after_sha256": { + "math": "5b63136552577a64d788dc3cd4552739d0d60f9e1adb63ec4dfb6932d56fc75d", + "test": "0a60a61022b4d9333882981dda4d09faf41cc36fd2e9406921fdf6e77b8821de", + "package": "7fa8fd86ba4b048bc7395cece337513c65936af275348074eadb443614b387d6" + }, + "independent_negative": { + "command": "rtk npm test", + "exit_code": 1, + "tests": 1, + "passed": 0, + "failed": 1 + }, + "independent_positive": { + "command": "rtk npm test", + "exit_code": 0, + "tests": 1, + "passed": 1, + "failed": 0 + }, + "native_recovery_return": { + "command": "/bin/bash -lc 'rtk npm test'", + "exitCode": 0, + "aggregatedOutput": "> test\n> node --test math.test.js\n✔ math.test.js (50.770919ms)\nℹ tests 1\nℹ suites 0\nℹ pass 1\nℹ fail 0\nℹ cancelled 0\nℹ skipped 0\nℹ todo 0\nℹ duration_ms 58.877967\n" + } + }, + "skills": { + "installation": { + "command": "rtk python3 tools/adoption/install_skills.py --manifest blueprints/runtime-workers/skills/manifest.json --project-dir --agent claude-code --skills-bin --json", + "exit_code": 0, + "installed": 136 + }, + "check": { + "command": "Same native recipe with --check-only", + "exit_code": 0, + "ok": 136 + }, + "project_canonical_skill_files": 136, + "project_claude_catalog_links": 136, + "actual_body_reads": [ + { + "name": "using-superpowers", + "sha256": "82c5c8866ad7f5dd4440ce66bd7806ba48a2f13771beae5cf112e53f08fe36ba", + "carrier": ".agents/skills", + "observation": "Native command read during accepted task" + }, + { + "name": "bridge-proof", + "sha256": "22ebfd605645bf4c0dc5c2154f9f169cd35982b9a0ba3a430aefccf37466acd8", + "carrier": ".claude/skills", + "observation": "Explicit task read of upstream fixture skill; additional to catalog; not Codex implicit discovery" + } + ], + "all_catalog_skills_task_qualified": false, + "optional_mcp_services_qualified": false, + "known_role_gaps": 15, + "known_capability_gaps": 3 + }, + "primary_runs": [ + { + "id": "sol-fix", + "exit_code": 0, + "status": "completed", + "duration_ms": 160281, + "requested_model": "cx/gpt-6.1-sol-max", + "requested_effort": "max", + "thread_relation": "New primary thread", + "command_executions": 15, + "file_changes": 1, + "reasoning_items": 7, + "agent_messages": 1, + "retained_failed_commands": 2, + "marker": "SDK_SOL_FIX_COMPLETE", + "native_usage": { + "cacheWriteInputTokens": 0, + "cachedInputTokens": 91904, + "inputTokens": 136549, + "outputTokens": 2818, + "reasoningOutputTokens": 1480, + "totalTokens": 139367 + }, + "usage_counting": "Historical snapshot already included in resumed thread; do not add again." + }, + { + "id": "sol-resume", + "exit_code": 0, + "status": "completed", + "duration_ms": 35159, + "requested_model": "cx/gpt-6.1-sol-max", + "requested_effort": "max", + "thread_relation": "Same native thread and worker state as sol-fix", + "command_executions": 3, + "file_changes": 0, + "marker": "SDK_SOL_RESUME_COMPLETE", + "native_usage": { + "cacheWriteInputTokens": 0, + "cachedInputTokens": 141696, + "inputTokens": 194470, + "outputTokens": 3347, + "reasoningOutputTokens": 1645, + "totalTokens": 197817 + }, + "usage_counting": "Latest cumulative snapshot for primary thread; count once." + }, + { + "id": "sol-wrong-resume", + "exit_code": 2, + "status": "failed", + "phase": "thread_resume", + "error_type": "InvalidRequestError", + "model_inference_submitted": false, + "cleanup_status": "closed", + "usage": null, + "observation": "Discriminating invalid thread negative control; no API inference submitted." + }, + { + "id": "sol-cancel", + "exit_code": 2, + "status": "deadline_exceeded", + "phase": "turn_run", + "deadline_seconds": 3, + "model_inference_submitted": true, + "interrupt_status": "requested", + "cleanup_status": "closed", + "usage": null, + "private_return_location": "sol-worker-cancel.log", + "native_result_file_created": false, + "remote_termination_verified": false + }, + { + "id": "sol-recovery", + "exit_code": 0, + "status": "completed", + "duration_ms": 10458, + "requested_model": "cx/gpt-6.1-sol-max", + "requested_effort": "max", + "thread_relation": "Fresh thread distinct from primary and interrupted thread", + "command_executions": 1, + "file_changes": 0, + "marker": "SDK_SOL_RECOVERY_COMPLETE", + "native_usage": { + "cacheWriteInputTokens": 0, + "cachedInputTokens": 30208, + "inputTokens": 30804, + "outputTokens": 123, + "reasoningOutputTokens": 42, + "totalTokens": 30927 + }, + "usage_counting": "Separate latest thread snapshot; count once." + } + ], + "transport": { + "native_api": "ResponsesLite", + "requested_model": "cx/gpt-6.1-sol-max", + "requested_effort": "max", + "observed_native_namespaces": [ + "functions", + "clock", + "collaboration" + ], + "tool_carrier": "input[].type=additional_tools", + "tool_namespace_count": 3, + "leaf_tool_count": null, + "fix_resume_cache_identity_sha256": "d3983d9d47d575fcb390de4827aab119ca921a659c29e4e7f988f024eadcb846", + "resumed_native_tool_prefix_sha256": "6723b69f57bec85922ff4e4b260b63d043be932e6013d32e3e63e318c15ab23e", + "fix_resume_cache_key_preserved": true, + "resume_tool_prefix_stable": true, + "completed_response_token_total_independently_reconciled": 228744, + "client_disconnect_after_completed_response": "Observer flow errors after terminal usage do not override successful native SDK result.", + "backend_model_identity_verified": false + }, + "usage_assessment": { + "scope": "Distinct successful native SDK threads only", + "input_tokens": 225274, + "output_tokens": 3470, + "total_tokens": 228744, + "cached_input_tokens_subset": 171904, + "reasoning_output_tokens_subset": 1687, + "latest_snapshots_counted_once": true, + "cached_and_reasoning_subsets_added_again": false, + "whole_task_usage": null, + "failed_cancelled_and_preparation_usage": null, + "provider_billing_cost_usd": null, + "token_savings_claim": false, + "exclusions": [ + "Interrupted turn", + "Both Claude gateway attempts", + "Native peer timeouts", + "Installation and preparation", + "Independent architecture review" + ] + }, + "claude_bridge": { + "requested_model": "dva/claude-opus-5-max", + "effort": "max", + "accepted": false, + "native_harness_preset": "claude_code", + "attempts": [ + { + "id": "claude-prototype", + "exit_code": 1, + "deadline_seconds": 90, + "duration_ms": 88790, + "tool_calls": 0, + "num_turns": 2, + "subtype": "error_during_execution", + "terminal_reason": "aborted_streaming", + "native_reported_cost_usd": 0, + "provider_billing_cost_usd": null, + "model_usage_latest_session_snapshot": {}, + "usage_last_native_result": { + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "input_tokens": 0, + "output_tokens": 0 + } + }, + { + "id": "claude-auth-repair", + "exit_code": 1, + "deadline_seconds": 90, + "duration_ms": 89015, + "tool_calls": 0, + "num_turns": 2, + "subtype": "error_during_execution", + "terminal_reason": "aborted_streaming", + "native_reported_cost_usd": 0, + "provider_billing_cost_usd": null, + "model_usage_latest_session_snapshot": {}, + "usage_last_native_result": { + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "input_tokens": 0, + "output_tokens": 0 + } + } + ], + "independent_messages_http_500_count": 16, + "successful_messages_usage_observed": false, + "bounded_sol_repair": "Apply upstream buildClaudeEnv child-only keyless gateway auth sentinel and gateway discovery; trial still failed. No causal attribution of first timeout to auth.", + "native_usage_zero_is_complete_provider_usage": false, + "bridge_semantics": "Devin translated prompt/tool bridge with estimated usage, finite tool-result truncation and restricted tool envelope; no native Anthropic/cache passthrough qualification." + }, + "checks": { + "authored_codex_integration": { + "passed": 6, + "duration_seconds": 11.615, + "exit_code": 0, + "owned_native_app_server_pid_absent_after_close": true, + "scope": "Real pinned SDK and native CLI against authored local SSE provider; tools/cache/resume/native counters/deadline/native PID exit/private originals/negative controls. Not upstream tests or live model acceptance." + }, + "preexisting_codex_upstream": { + "passed": 266, + "failed": 1, + "skipped": 38, + "exit_code": 1, + "scope": "Prior owner unchanged SDK source suite; retained unrelated formatter-driver expectation failure, not replaced by local checks." + }, + "unchanged_upstream_claude_sdk": { + "revision": "f2204bb956bab02907aaf3cb88eb9dead28eaa35", + "src_and_tests_clean": true, + "python": "3.13.15", + "mcp": "2.2.0", + "passed": 1587, + "skipped": 6, + "duration_seconds": 28.46, + "exit_code": 0, + "scope": "SDK source tests; not OmniRoute inference acceptance." + }, + "authored_claude_integration": { + "passed": 24, + "exit_code": 0, + "scope": "Synthetic local configuration, usage, lifecycle and disarmed/armed negative controls." + }, + "observer_integration": { + "passed": 5, + "exit_code": 0, + "scope": "Authored fragmented-stream identity, overflow/unknown, endpoint and native tool-carriage checks." + }, + "skill_frontmatter": { + "command": "rtk uv run --with pyyaml==6.0.3 python /scripts/quick_validate.py .claude/skills/omniroute-runtime-worker", + "exit_code": 0, + "returned_output": "Skill is valid!", + "scope": "Metadata shape only; not a live Claude-coordinator dispatch." + }, + "owned_observer_shutdown": { + "exit_code": 130, + "listener_after_stop": "No listener at owned observer port", + "existing_gateway_reconfigured": false + } + }, + "cooperation": { + "native_interactive_accounts_retained": true, + "owner_handoff": "https://github.com/seathatflowsinourveins/native-agent-stack/pull/535#issuecomment-5913868401", + "claude_peer_branch": "claude/pi-omni-trial-20260929", + "peer_pr": "https://github.com/seathatflowsinourveins/native-agent-stack/pull/524", + "native_background_peer": { + "model": "claude-opus-5-5", + "effort": "max", + "tools": [ + "ListAgents", + "SendMessage" + ], + "owner_contacts_made": true, + "final_packet_received": false, + "stopped_only_owned_session": true, + "usage": null + }, + "native_final_analytical_review": { + "model": "claude-opus-5-5", + "effort": "max", + "deadline_seconds": 240, + "exit_code": 124, + "result_received": false, + "usage": null, + "approval_received": false + }, + "bare_review_negative_control": { + "exit_code": 1, + "returned_error": "authentication_failed", + "native_counters_zero": true, + "meaning": "Bare disables native authentication loading; this does not establish a missing native account." + }, + "astra_escalation": { + "trigger": "Consequential bridge architecture and a Claude gateway failure unresolved after one bounded Sol auth repair.", + "effort": "max", + "mode": "Independent original-source and owned-artifact audit; no additional model trial.", + "verdict": "Accept bounded Codex SDK Sol-Max coding lifecycle; reject promotion of failed Claude bridge.", + "limits": "No Claude coordinator invocation, backend identity, complete billing, all skills qualification or remote cancellation proved." + } + }, + "corrections": [ + "Top-level tools absence was a faulty local ResponsesLite oracle. The original source and wire carry additional_tools under input; failed KeyError retained, corrected meaningful checks passed.", + "Keyless gateway child auth follows OmniRoute buildClaudeEnv. Applying it did not repair the observed Claude 500 failure.", + "Native --bare authentication failure does not prove native account absence. Normal analytical review later timed out without approval.", + "An excluded sparse-checkout file is not an upstream absence; exact tagged git show recovered the launcher source.", + "Cancellation returned its native status in sol-worker-cancel.log; no sol-native-cancel.json was created.", + "Skill validator initially lacked PyYAML in system Python; supported isolated uv execution with pinned PyYAML passed without global installation." + ], + "limitations": [ + "One arithmetic fixture and lifecycle acceptance; no universal SDK or model quality ranking.", + "Actual provider trials invoked the SDK from root, rather than through a Claude coordinator. Native project dispatch skill is supplied and structurally checked; its coordinator invocation remains unmeasured.", + "Native Codex SDK remains the incumbent. The separate frozen three-arm SDK gate remains unresolved.", + "Native gateway requested/returned model labels are not backend attestation.", + "All 136 skills are available in the owned project, with two bodies exercised; full role coverage and optional service acceptance remain incomplete.", + "Native Codex repeated in-process fixtures emit stdout/stderr ResourceWarnings; standalone per-invocation child exit is qualified separately.", + "Complete provider usage, spending, remote cancellation and token savings remain unknown.", + "Public record is sanitized selected actual return fields and independent observations; original private returned artifacts remain outside the checkout." + ] +} diff --git a/manifests/evidence.json b/manifests/evidence.json index c5c67f164..dd4aea22f 100644 --- a/manifests/evidence.json +++ b/manifests/evidence.json @@ -1,6 +1,27 @@ { "schema_version": 1, "receipts": [ + { + "id": "omniroute-runtime-workers-20260930", + "kind": "native_model_e2e", + "component_ids": [ + "codex", + "claude-code", + "omniroute" + ], + "claim": "The retained official Codex SDK Sol-Max worker passed one upstream coding fixture, native resume and fresh recovery through the selected OmniRoute Responses lane. Interrupted usage and Claude bridge qualification remain unknown/failed.", + "limitations": [ + "One arithmetic fixture and lifecycle acceptance; no universal SDK or model quality ranking.", + "Actual provider trials invoked the SDK from root, rather than through a Claude coordinator. Native project dispatch skill is supplied and structurally checked; its coordinator invocation remains unmeasured.", + "Native Codex SDK remains the incumbent. The separate frozen three-arm SDK gate remains unresolved.", + "Native gateway requested/returned model labels are not backend attestation.", + "All 136 skills are available in the owned project, with two bodies exercised; full role coverage and optional service acceptance remain incomplete.", + "Native Codex repeated in-process fixtures emit stdout/stderr ResourceWarnings; standalone per-invocation child exit is qualified separately.", + "Complete provider usage, spending, remote cancellation and token savings remain unknown.", + "Public record is sanitized selected actual return fields and independent observations; original private returned artifacts remain outside the checkout." + ], + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json" + }, { "id": "memory-lifecycle-probe-20260921", "kind": "native_cli_e2e", @@ -3697,6 +3718,11 @@ "sha256": "a1ec95b039955774e7873393a5146ce6001a711aaf6278d76f387d853a057806", "bytes": 2884 }, + { + "path": ".claude/skills/omniroute-runtime-worker/SKILL.md", + "sha256": "857a00f0c3f4088a20662f32f422b30c4697d0c267c0db1f9dbb95dfcbe39ce5", + "bytes": 2248 + }, { "path": ".gitattributes", "sha256": "b3ffd27e5ca28d7fd987dc7c594601e4532660ddfeb4992ae92b3916ecb45e9f", @@ -5518,6 +5544,11 @@ "sha256": "de31f07cf4ac3f1d32fc64ef94796a98a9aec39fb2a10945dfd1d13e37cdb246", "bytes": 56660 }, + { + "path": "blueprints/convergence-practice/omniroute-runtime-workers/experiment.json", + "sha256": "fbc8fb60192c306625a889e948bd2ca682dba9d0eeffd9bf768663b35679d324", + "bytes": 25944 + }, { "path": "blueprints/convergence-practice/protocol.json", "sha256": "7176889bb4f8e3839c5230918c1e23ff89bdd3778a8f333db2ea881731a08e45", @@ -14798,6 +14829,11 @@ "sha256": "b2d99153c8dffb6169923e9129cfb6e4343cd9f5fc443ad8839fa5f162e20c1e", "bytes": 37375 }, + { + "path": "docs/decisions/2026-09-30-omniroute-runtime-workers.md", + "sha256": "92ce5364d15857b4bf9392779b829f0d1fcca7621c54d3dfe64009d7a91999ca", + "bytes": 8079 + }, { "path": "docs/direct-results.md", "sha256": "12a511fee11f22c90b9b622701d5485be9c8247167102b5768d694244f939a5b", @@ -43743,6 +43779,11 @@ "sha256": "0f6a0c171872cde9689d9d5f2ff60b881ae2328b96769dc78613f625cf9d1017", "bytes": 16128 }, + { + "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", + "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e", + "bytes": 17754 + }, { "path": "evidence/receipts/osv-oauthlib-pyjwt-reachability-20260929.json", "sha256": "f89e3a45ac10d44d00c268cc617c1fb7b5f77636fb1150af3c9e7bf4b26441ef", @@ -44083,6 +44124,36 @@ "sha256": "2ed3323db76d0104327a0c0bb35f00cf6a05018bdd9f49982b0c279cf2540871", "bytes": 8495 }, + { + "path": "examples/claude-runtime-sdk/README.md", + "sha256": "eb8e0d9f5f794c5fe66d3c7d402dc850ee666a2317c3fc66763f5ebd275fb87c", + "bytes": 9939 + }, + { + "path": "examples/claude-runtime-sdk/tests/check_controls.py", + "sha256": "21a79c84a780a900fb365c0478bf79af5ed1d55a9c20f59b5859368b71fe9dcf", + "bytes": 1010 + }, + { + "path": "examples/claude-runtime-sdk/tests/test_worker.py", + "sha256": "2e748b56185fc8aa8eb519a371d4524327fe5fe9f4bfdfda4f60bb6510f96dea", + "bytes": 17488 + }, + { + "path": "examples/claude-runtime-sdk/verification.md", + "sha256": "980b4f2ffbf49ee9ca2ab0127a4bc90c1d56c401c2cbb74d78b9a9dbe1f05ae1", + "bytes": 8558 + }, + { + "path": "examples/claude-runtime-sdk/worker.py", + "sha256": "92b6077da5f659a9798d61433b73920903dd2637dd4b4ee914e42995d111abf9", + "bytes": 19866 + }, + { + "path": "examples/claude-runtime-sdk/worker.py.lock", + "sha256": "79f1e72c87e1a934cf532a6ee929e22b1defcb2476317e24d68c1124913235c8", + "bytes": 96322 + }, { "path": "examples/codex-mcp.toml.example", "sha256": "6203fdcb819d183fae1ac01ae2eda447252f2f8d07de53d82cf947845a07e6c0", @@ -44138,6 +44209,36 @@ "sha256": "4b5e20c8785fc6d9d81a6cbaf752648e79afc5a32888300b525a2f4b64f09e63", "bytes": 378 }, + { + "path": "examples/omniroute-codex-sdk/README.md", + "sha256": "ec992256bb6b43262c3a7fe019fcfa9bd428bf04fd123e50b36b2ed7fa83c46a", + "bytes": 10099 + }, + { + "path": "examples/omniroute-codex-sdk/checks.json", + "sha256": "26dab6f4fa94512bbe8965f51fb29845ca07e8c4664765e484cd56bc80f9b610", + "bytes": 4632 + }, + { + "path": "examples/omniroute-codex-sdk/test_worker.py", + "sha256": "ea30d5bd0568f1e179e6460647ef61f2ca1ca025bda574f5f35a315eeee2ae2a", + "bytes": 12585 + }, + { + "path": "examples/omniroute-codex-sdk/test_worker.py.lock", + "sha256": "15e5e7cfeec11ac86d8f081742c726c0d70326b480894a81e5cc76a7d9225c44", + "bytes": 12842 + }, + { + "path": "examples/omniroute-codex-sdk/worker.py", + "sha256": "8dfa1799dc2ce034548eb2581befe61bef480728cc541a451e960bb48decc651", + "bytes": 11517 + }, + { + "path": "examples/omniroute-codex-sdk/worker.py.lock", + "sha256": "15e5e7cfeec11ac86d8f081742c726c0d70326b480894a81e5cc76a7d9225c44", + "bytes": 12842 + }, { "path": "examples/promptfoo-nemotron-upstream/promptfooconfig.yaml", "sha256": "07c64ff592209af4ac973d0cadf3bb69099cbf3ab79f89e5129f182c93a32df2", @@ -45908,6 +46009,26 @@ "sha256": "d5cfcfbd61bcfcb1808270deab7e793d4021c8dd0c3079fe5ff71ee723ab46e6", "bytes": 4963 }, + { + "path": "tools/runtime-worker-evidence/README.md", + "sha256": "b614d175056395e2f88818b57f27c76f435b97512afa4ef7444b43316a041c8d", + "bytes": 2383 + }, + { + "path": "tools/runtime-worker-evidence/checks.json", + "sha256": "1a739e258ed6aa5d0fac22a03185d4457f222fd0d6575545d26f8237c3fdeca4", + "bytes": 3470 + }, + { + "path": "tools/runtime-worker-evidence/gateway_observer.py", + "sha256": "d4569ed6efef53015eb1619bf5591f91530476896fd6e18f4c2ba44ec07a6f97", + "bytes": 5702 + }, + { + "path": "tools/runtime-worker-evidence/test_gateway_observer.py", + "sha256": "b5cba9a4a0ffacba92a1194644ee6cde96e267246bc24f302876d4ad5bf5e8db", + "bytes": 4010 + }, { "path": "tools/skill-usage/README.md", "sha256": "34cda0de60388ff139f55bec45f875ca6f104471913120d540c072f9b3f05c01", @@ -46285,6 +46406,7 @@ } ], "convergence_records": [ + "blueprints/convergence-practice/omniroute-runtime-workers/experiment.json", "blueprints/blind-catalog-convergence/experiment.json", "blueprints/blind-catalog-convergence/memory-experiment.json", "blueprints/catalog-runtime-review/experiment.json", diff --git a/tools/runtime-worker-evidence/README.md b/tools/runtime-worker-evidence/README.md new file mode 100644 index 000000000..035481c6e --- /dev/null +++ b/tools/runtime-worker-evidence/README.md @@ -0,0 +1,29 @@ +# Owned worker gateway observation + +This optional acceptance observer uses [mitmproxy v12.2.3](https://github.com/mitmproxy/mitmproxy/tree/6c09d56e4c29a92f5ad01b03199977584b8ea14f), its supported [reverse mode](https://docs.mitmproxy.org/stable/concepts/modes/#reverse-proxy), and the native [`responseheaders` streaming callback](https://github.com/mitmproxy/mitmproxy/blob/6c09d56e4c29a92f5ad01b03199977584b8ea14f/examples/addons/http-stream-modify.py). It observes a dedicated worker's loopback HTTP traffic. It is a local integration check; it is not an upstream acceptance test or backend identity attestation. + +Set `STACK_WORKER_OBSERVATION` to a new private JSONL file outside the checkout, select an unused loopback port, and run: + +```sh +rtk uv tool run --from mitmproxy==12.2.3 mitmdump --version +rtk uv tool run --from mitmproxy==12.2.3 mitmdump --quiet \ + --mode reverse:http://127.0.0.1:20128 --listen-host 127.0.0.1 \ + --listen-port --set confdir= \ + --set flow_detail=0 --scripts tools/runtime-worker-evidence/gateway_observer.py +``` + +For that acceptance run alone, point the worker's scoped gateway URL to the observer. Keep existing client and gateway settings. Do not use flow recording, local capture, TLS interception or another session's traffic. Stop only the owned observer process after the run. + +The addon records model, effort, tool names/count, body length/hash, cache-key hash, status and selected Responses usage counters. It retains no credential values, request content, tool arguments or returned text, and returns response chunks unchanged. Request and flow IDs stay private. A frame over 2 MiB marks usage capture incomplete. Missing usage stays unknown. Gateway/provider counters are not a savings measurement; reasoning and cached-token counters are subsets and must not be added to totals. + +Run the authored observer checks in the same pinned dependency environment: + +```sh +rtk uv run --with mitmproxy==12.2.3 python -m unittest discover \ + -s tools/runtime-worker-evidence -p 'test_*.py' +``` + +Bare system Python does not supply mitmproxy; that invocation failed on import. +The checks preserve every fragmented streaming byte, reject unrelated endpoints, +retain unknown/overflow usage and observe native ResponsesLite tools under +`input[].type=additional_tools`. The namespace count is not a leaf-tool count. diff --git a/tools/runtime-worker-evidence/checks.json b/tools/runtime-worker-evidence/checks.json new file mode 100644 index 000000000..7b9bb460f --- /dev/null +++ b/tools/runtime-worker-evidence/checks.json @@ -0,0 +1,81 @@ +{ + "kind": "authored_local_integration_checks", + "sources": [ + "https://github.com/mitmproxy/mitmproxy/tree/6c09d56e4c29a92f5ad01b03199977584b8ea14f", + "https://github.com/seathatflowsinourveins/native-agent-stack/blob/5cfa2400e3ebb4aefb8419135345c1fa92b05409/scripts/validate.py" + ], + "scope": "Metadata/stream integration checks and publication integrity only; no new provider trial.", + "attempts": [ + { + "command": "Native pre-commit gitleaks git --pre-commit --staged --redact", + "exit_code": 1, + "returned_rule": "generic-api-key", + "finding": "Public receipt cache-identifier SHA-256 metadata name matched API-key syntax.", + "correction": "Renamed the metadata field to cache identity; retained the same independently observed digest. No allowlist or hook bypass." + }, + { + "command": "rtk python3 -m unittest discover -s tools/runtime-worker-evidence -p 'test_*.py'", + "exit_code": 1, + "returned_error": "ModuleNotFoundError: No module named 'mitmproxy'", + "passed": 0, + "errors": 5, + "correction": "Use the selected native isolated dependency environment." + }, + { + "command": "rtk uv run --with mitmproxy==12.2.3 python -m unittest discover -s tools/runtime-worker-evidence -p 'test_*.py'", + "exit_code": 0, + "returned_output": "Ran 5 tests in 0.101s\nOK", + "passed": 5 + }, + { + "command": "rtk python3 /scripts/quick_validate.py .claude/skills/omniroute-runtime-worker", + "exit_code": 1, + "returned_error": "ModuleNotFoundError: No module named 'yaml'", + "correction": "Use supported isolated uv with pinned PyYAML; no global installation." + }, + { + "command": "rtk uv run --with pyyaml==6.0.3 python /scripts/quick_validate.py .claude/skills/omniroute-runtime-worker", + "exit_code": 0, + "returned_output": "Skill is valid!", + "limit": "Structural check; actual native Claude dispatch remains unmeasured." + }, + { + "command": "rtk python3 scripts/validate_convergence.py blueprints/convergence-practice/omniroute-runtime-workers/experiment.json", + "exit_code": 1, + "returned_error": "Seven administrative observation task/role IDs were undeclared.", + "correction": "Declared the existing tasks and installer role; no model call or result changed." + }, + { + "command": "Same scoped convergence validator after metadata correction", + "exit_code": 0, + "returned_output": "record[0]: valid" + }, + { + "command": "rtk python3 scripts/validate.py", + "exit_code": 1, + "returned_error": "Hash-listed project skill was ignored by Git and not tracked.", + "correction": "Force-added only the owned project skill file; no broad ignore rule change." + }, + { + "command": "Publication validation after force-adding owned project skill", + "exit_code": 0, + "returned_output": { + "components": 69, + "hashed_files": 8102, + "profiles": 4, + "receipts": 172, + "status": "passed" + }, + "limit": "Integrity and scope only; final registration adds this check record." + }, + { + "command": "Both pinned SDK runner --help commands", + "exit_code": 0, + "correction": "Corrected drafted Claude command option names against installed help; no capability absence inferred." + }, + { + "command": "rtk git diff --check", + "exit_code": 0 + } + ] +} diff --git a/tools/runtime-worker-evidence/gateway_observer.py b/tools/runtime-worker-evidence/gateway_observer.py new file mode 100644 index 000000000..ce329d56e --- /dev/null +++ b/tools/runtime-worker-evidence/gateway_observer.py @@ -0,0 +1,139 @@ +"""Value-free observation of an owned worker's loopback gateway traffic. + +Use mitmproxy 12.2.3 (6c09d56e4c29a92f5ad01b03199977584b8ea14f) +in reverse mode. Sources: docs.mitmproxy.org/stable/concepts/modes/ +and that tag's examples/addons/http-stream-simple.py, http-stream-modify.py. +This addon observes requests and returns every response chunk unchanged. +It is a local integration observer, not an upstream test or a provider oracle. +Do not use it to capture another session, write flows, or intercept TLS. +""" + +from __future__ import annotations + +import hashlib +import json +import os +from pathlib import Path +from typing import Any + +from mitmproxy import http + +OUTPUT = Path(os.environ["STACK_WORKER_OBSERVATION"]) +MAX_FRAME = 2 * 1024 * 1024 + + +def emit(row: dict[str, Any]) -> None: + """Append only selected metadata; never headers, prompts or tool arguments.""" + fd = os.open(OUTPUT, os.O_WRONLY | os.O_APPEND | os.O_CREAT, 0o600) + with os.fdopen(fd, "a") as stream: + stream.write(json.dumps(row, separators=(",", ":")) + "\n") + + +def counters(value: Any) -> dict[str, Any] | None: + if not isinstance(value, dict): + return None + result: dict[str, Any] = {} + for key in ("input_tokens", "output_tokens", "total_tokens"): + if type(value.get(key)) is int: + result[key] = value[key] + for key in ("input_tokens_details", "output_tokens_details"): + details = value.get(key) + if isinstance(details, dict): + result[key] = { + name: count for name, count in details.items() + if name in ("cached_tokens", "reasoning_tokens") and type(count) is int + } + return result or None + + +def request(flow: http.HTTPFlow) -> None: + if flow.request.method != "POST": + return + path = flow.request.path.split("?", 1)[0] + if path not in ("/v1/responses", "/v1/messages"): + return + body = flow.request.content or b"" + try: + data = json.loads(body) + except (ValueError, UnicodeError): + emit({"event": "unparsed_request", "flow": flow.id, "path": path}) + return + cache_key = data.get("prompt_cache_key") + tools = data.get("tools") + tool_source = "top_level" if isinstance(tools, list) else None + native_ids = [] + # Codex rust-v0.159.2 core/src/client.rs:902-933: ResponsesLite + # carries native tool declarations in input.additional_tools, not tools. + if not isinstance(tools, list) and isinstance(data.get("input"), list): + declarations = [x for x in data["input"] + if isinstance(x, dict) and x.get("type") == "additional_tools"] + if declarations: + tools = [tool for declaration in declarations + for tool in declaration.get("tools", [])] + tool_source = "input.additional_tools" + native_ids = [hashlib.sha256(x["id"].encode()).hexdigest() + for x in declarations if isinstance(x.get("id"), str)] + names = [] + for tool in tools if isinstance(tools, list) else []: + if isinstance(tool, dict): + name = tool.get("name") or (tool.get("function") or {}).get("name") + if isinstance(name, str): + names.append(name) + reasoning = data.get("reasoning") + flow.metadata["stack_worker_observed"] = True + emit({ + "event": "request", "flow": flow.id, "path": path, + "request_keys": sorted(data), + "model": data.get("model"), + "effort": reasoning.get("effort") if isinstance(reasoning, dict) else None, + "request_bytes": len(body), "request_sha256": hashlib.sha256(body).hexdigest(), + "cache_key_sha256": hashlib.sha256(cache_key.encode()).hexdigest() + if isinstance(cache_key, str) else None, + "tool_count": len(tools) if isinstance(tools, list) else None, + "tool_names": names, + "tool_source": tool_source, "native_tool_id_hashes": native_ids, + "cache_markers_present": b'"cache_control"' in body, + }) + + +def responseheaders(flow: http.HTTPFlow) -> None: + if not flow.metadata.get("stack_worker_observed") or flow.response is None: + return + emit({"event": "response_headers", "flow": flow.id, + "status": flow.response.status_code}) + pending = bytearray() + overflow = False + + def observe(chunk: bytes) -> bytes: + nonlocal overflow + if not overflow: + pending.extend(chunk) + if len(pending) > MAX_FRAME: + pending.clear() + overflow = True + emit({"event": "usage_capture_overflow", "flow": flow.id}) + while b"\n" in pending: + line, _, rest = pending.partition(b"\n") + pending[:] = rest + if not line.startswith(b"data:"): + continue + try: + event = json.loads(line[5:].strip()) + except (ValueError, UnicodeError): + continue + if isinstance(event, dict) and event.get("type") == "response.completed": + response = event.get("response", {}) + emit({"event": "response_completed", "flow": flow.id, + "usage": counters(response.get("usage")) + if isinstance(response, dict) else None}) + if chunk == b"": + emit({"event": "stream_closed", "flow": flow.id}) + return chunk + + # Native mitmproxy streaming callback; identity preserves response bytes. + flow.response.stream = observe + + +def error(flow: http.HTTPFlow) -> None: + if flow.metadata.get("stack_worker_observed"): + emit({"event": "flow_error", "flow": flow.id}) diff --git a/tools/runtime-worker-evidence/test_gateway_observer.py b/tools/runtime-worker-evidence/test_gateway_observer.py new file mode 100644 index 000000000..eddb92e42 --- /dev/null +++ b/tools/runtime-worker-evidence/test_gateway_observer.py @@ -0,0 +1,83 @@ +"""Local stream-fidelity controls; these are not upstream/provider tests.""" + +import importlib.util +import json +import os +import unittest +from pathlib import Path +from types import SimpleNamespace + + +class GatewayObserverTests(unittest.TestCase): + def setUp(self): + os.environ["STACK_WORKER_OBSERVATION"] = "/unused-owned-test-output" + path = Path(__file__).with_name("gateway_observer.py") + spec = importlib.util.spec_from_file_location("gateway_observer", path) + self.addon = importlib.util.module_from_spec(spec) + spec.loader.exec_module(self.addon) + self.rows = [] + self.addon.emit = self.rows.append + self.body = json.dumps({ + "model": "cx/gpt-6.1-sol", "reasoning": {"effort": "max"}, + "prompt_cache_key": "owned-session", "input": "private-fixture-content", + "tools": [{"type": "function", "name": "shell"}], + }).encode() + self.flow = SimpleNamespace( + id="owned-flow", metadata={}, + request=SimpleNamespace(method="POST", path="/v1/responses", content=self.body), + response=SimpleNamespace(status_code=200, stream=None), + ) + + def test_fragmented_stream_preserves_every_byte_and_observes_terminal_usage(self): + self.addon.request(self.flow) + self.addon.responseheaders(self.flow) + wire = b'data: {"type":"response.completed","response":{"usage":{"input_tokens":9,"output_tokens":4,"total_tokens":13,"input_tokens_details":{"cached_tokens":3},"output_tokens_details":{"reasoning_tokens":2}}}}\n\n' + chunks = [wire[:7], wire[7:31], wire[31:], b""] + returned = b"".join(self.flow.response.stream(chunk) for chunk in chunks) + self.assertEqual(returned, wire) + self.assertEqual(self.flow.request.content, self.body) + completed = [r for r in self.rows if r["event"] == "response_completed"] + self.assertEqual(len(completed), 1) + self.assertEqual(completed[0]["usage"]["total_tokens"], 13) + self.assertNotIn("private-fixture-content", json.dumps(self.rows)) + + def test_absent_usage_stays_unknown(self): + self.addon.request(self.flow) + self.addon.responseheaders(self.flow) + wire = b'data: {"type":"response.completed","response":{}}\n\n' + self.assertEqual(self.flow.response.stream(wire), wire) + self.assertIsNone(self.rows[-1]["usage"]) + + def test_native_responses_lite_tools_are_observed_without_flattening_request(self): + self.flow.request.content = json.dumps({ + "model": "cx/gpt-6.1-sol-max", "input": [{ + "type": "additional_tools", "id": "stable-native-tools", + "role": "developer", "tools": [{"type": "namespace", "name": "functions"}], + }], + }).encode() + original = self.flow.request.content + self.addon.request(self.flow) + self.assertEqual(self.flow.request.content, original) + self.assertEqual(self.rows[0]["tool_source"], "input.additional_tools") + self.assertEqual(self.rows[0]["tool_names"], ["functions"]) + self.assertEqual(len(self.rows[0]["native_tool_id_hashes"]), 1) + + def test_oversized_frame_exposes_incomplete_capture_and_preserves_tail(self): + self.addon.request(self.flow) + self.addon.responseheaders(self.flow) + self.addon.MAX_FRAME = 128 + wire = b"data: " + b"x" * 256 + b"TAIL_MUST_SURVIVE\n\n" + self.assertEqual(self.flow.response.stream(wire), wire) + self.assertTrue(any(r["event"] == "usage_capture_overflow" for r in self.rows)) + self.assertFalse(any(r["event"] == "response_completed" for r in self.rows)) + + def test_wrong_endpoint_does_not_claim_worker_observation(self): + self.flow.request.path = "/v1/unselected" + self.addon.request(self.flow) + self.addon.responseheaders(self.flow) + self.assertEqual(self.rows, []) + self.assertIsNone(self.flow.response.stream) + + +if __name__ == "__main__": + unittest.main() From aa53a90f0854725edfec7feca0e42c7394274704 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 12:28:58 -0400 Subject: [PATCH 07/14] docs(foundation): link exact executed SDK sources --- docs/decisions/2026-09-30-omniroute-runtime-workers.md | 6 ++++++ manifests/evidence.json | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/decisions/2026-09-30-omniroute-runtime-workers.md b/docs/decisions/2026-09-30-omniroute-runtime-workers.md index 889902238..a9c541222 100644 --- a/docs/decisions/2026-09-30-omniroute-runtime-workers.md +++ b/docs/decisions/2026-09-30-omniroute-runtime-workers.md @@ -49,6 +49,12 @@ failed before inference; a three-second deadline requested native interruption; a fresh thread then passed. The cancellation result is in its private log, not an original-result JSON file. Remote termination remains unverified. +The byte-exact executed sources are also retained in this branch's public +[Sol source commit](https://github.com/seathatflowsinourveins/native-agent-stack/blob/9edd76e9f9f817e818b59b7b5cfd16e329317ad0/examples/omniroute-codex-sdk/worker.py) +and [Claude source commit](https://github.com/seathatflowsinourveins/native-agent-stack/blob/38e4ec6f69d23c663f60c44c311217f7239e448d/examples/claude-runtime-sdk/worker.py). +Later formatting commits preserve the same AST; the receipt names original +worker commits and full executed/final SHA-256 values. + The gateway observer confirms Max effort and native ResponsesLite tool carriage under `input[].type=additional_tools`. The first authored oracle incorrectly expected top-level `tools`; original tagged source corrected that failed oracle. diff --git a/manifests/evidence.json b/manifests/evidence.json index dd4aea22f..80deacbdd 100644 --- a/manifests/evidence.json +++ b/manifests/evidence.json @@ -14831,8 +14831,8 @@ }, { "path": "docs/decisions/2026-09-30-omniroute-runtime-workers.md", - "sha256": "92ce5364d15857b4bf9392779b829f0d1fcca7621c54d3dfe64009d7a91999ca", - "bytes": 8079 + "sha256": "5ed6f31d2f89ab8f9ab01f5701a93b61311205f0b376b1b90ceb4df2138c4503", + "bytes": 8625 }, { "path": "docs/direct-results.md", From 43b13a4bd8f7721f6220d909ae209d1dd7213448 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 12:41:35 -0400 Subject: [PATCH 08/14] fix(ci): scan native SDK script locks with supported UV extractor --- .github/osv-scanner-lockfiles.json | 12 +++++ .../2026-09-30-omniroute-runtime-workers.md | 10 ++++ manifests/evidence.json | 21 +++++--- tests/test_osv_lockfile_coverage.py | 9 +++- tools/runtime-worker-evidence/checks.json | 6 +++ tools/runtime-worker-evidence/osv-check.json | 50 +++++++++++++++++++ 6 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 tools/runtime-worker-evidence/osv-check.json diff --git a/.github/osv-scanner-lockfiles.json b/.github/osv-scanner-lockfiles.json index 0673b1665..e80b17ef5 100644 --- a/.github/osv-scanner-lockfiles.json +++ b/.github/osv-scanner-lockfiles.json @@ -1,6 +1,18 @@ { "description": "Every tracked dependency lockfile or manifest that security-scan.yml's osv-scanner job scans. A lockfile entry without a parser lets OSV-Scanner infer it from the file name; parser names the OSV-Scanner v2 extractor for names it cannot infer (--lockfile=:). A covered_by_lockfile entry is a manifest OSV-Scanner v2.6.0 has no source extractor for; its sibling lockfile is scanned instead. An excluded entry is a tracked lockfile deliberately left out of the scan; it needs a reason and an evidence path, and only a deliberately vulnerable test fixture qualifies. tests/test_osv_lockfile_coverage.py fails when a tracked lockfile or manifest is in none of the three lists.", "lockfiles": [ + { + "path": "examples/claude-runtime-sdk/worker.py.lock", + "parser": "uv.lock" + }, + { + "path": "examples/omniroute-codex-sdk/worker.py.lock", + "parser": "uv.lock" + }, + { + "path": "examples/omniroute-codex-sdk/test_worker.py.lock", + "parser": "uv.lock" + }, { "path": ".github/requirements-ci.txt", "parser": "requirements.txt" diff --git a/docs/decisions/2026-09-30-omniroute-runtime-workers.md b/docs/decisions/2026-09-30-omniroute-runtime-workers.md index a9c541222..e5626eb4c 100644 --- a/docs/decisions/2026-09-30-omniroute-runtime-workers.md +++ b/docs/decisions/2026-09-30-omniroute-runtime-workers.md @@ -66,6 +66,16 @@ Codex upstream-suite passing claim is made. Repeated calls in one Python process also expose native SDK pipe ResourceWarnings. Standalone child exit is checked; a long-running in-process pool is unqualified. +The required pre-push gate caught the three new uv script locks missing from the +dependency scan inventory. Registered each with the supported `uv.lock` override +from [OSV-Scanner v2.6.0 source](https://github.com/google/osv-scanner/blob/e840a6e8adb14b7777c78e26cfbf6e2abc1d1fc6/pkg/osvscanner/internal/scanners/lockfile.go#L62). +The suppression guard now recognizes explicit UV parsers for script-lock names; +its adversarial vulnerable-pin check remains effective. Thirty authored registry +checks passed. A checksum-verified native scanner extracted 8, 8 and 32 packages +from the three respective locks and returned exit0 with no known findings. The +[selected actual result](../../tools/runtime-worker-evidence/osv-check.json) +retains this dated scope; it does not certify all native/runtime dependencies. + The supported pinned skill installer installed 136 catalog skills in the owned project, and its independent check reported 136 OK. Native task execution read `using-superpowers` plus the additional upstream `bridge-proof` fixture skill. diff --git a/manifests/evidence.json b/manifests/evidence.json index 80deacbdd..e3124ffad 100644 --- a/manifests/evidence.json +++ b/manifests/evidence.json @@ -3755,8 +3755,8 @@ }, { "path": ".github/osv-scanner-lockfiles.json", - "sha256": "c0025db3159bef98f27abaa32cbd1522067a7d3f114f5c339893883d6fc39dcd", - "bytes": 10060 + "sha256": "2022223f013b7a264b44d57aaacd5249dabb2e8b73b1099581290085c7ee3cb8", + "bytes": 10364 }, { "path": ".github/osv-scanner.toml", @@ -14831,8 +14831,8 @@ }, { "path": "docs/decisions/2026-09-30-omniroute-runtime-workers.md", - "sha256": "5ed6f31d2f89ab8f9ab01f5701a93b61311205f0b376b1b90ceb4df2138c4503", - "bytes": 8625 + "sha256": "1b9834cbcbff17ef74205d5093bc7e5b790b28cd5f9eeccff34fce4a049a6559", + "bytes": 9433 }, { "path": "docs/direct-results.md", @@ -45606,8 +45606,8 @@ }, { "path": "tests/test_osv_lockfile_coverage.py", - "sha256": "192b167f797edde99ec08e0303339ab26d5259bcf076a786117738be998faf90", - "bytes": 38017 + "sha256": "7dc3770432668f732cbffb7fbe189b6e7b63d6ac7ef91fda8c3146bf0d7a77df", + "bytes": 38501 }, { "path": "tests/test_path_safety.py", @@ -46016,14 +46016,19 @@ }, { "path": "tools/runtime-worker-evidence/checks.json", - "sha256": "1a739e258ed6aa5d0fac22a03185d4457f222fd0d6575545d26f8237c3fdeca4", - "bytes": 3470 + "sha256": "094cd7785fabc277508bc4ed90bac60a4e98dacdca7b51f50f5731608cc5e80c", + "bytes": 3851 }, { "path": "tools/runtime-worker-evidence/gateway_observer.py", "sha256": "d4569ed6efef53015eb1619bf5591f91530476896fd6e18f4c2ba44ec07a6f97", "bytes": 5702 }, + { + "path": "tools/runtime-worker-evidence/osv-check.json", + "sha256": "0d31c8900e8f5475c2fbe04f26d09493e2e507354c8c99e5b35a50c079e318b7", + "bytes": 2778 + }, { "path": "tools/runtime-worker-evidence/test_gateway_observer.py", "sha256": "b5cba9a4a0ffacba92a1194644ee6cde96e267246bc24f302876d4ad5bf5e8db", diff --git a/tests/test_osv_lockfile_coverage.py b/tests/test_osv_lockfile_coverage.py index e59068cb7..a540334a8 100644 --- a/tests/test_osv_lockfile_coverage.py +++ b/tests/test_osv_lockfile_coverage.py @@ -39,7 +39,9 @@ # File names OSV-Scanner infers without a parser prefix, and the parsers this inventory uses. # package-lock.json is listed in the pinned v2.6.0 supported-lockfiles documentation. INFERRED = {"requirements.txt", "uv.lock", "package-lock.json", "pnpm-lock.yaml", "packages.lock.json"} -PARSERS = {"requirements.txt", "packages.lock.json"} +# OSV-Scanner v2.6.0 lockfile.go maps "uv.lock" to the native UV extractor; +# an explicit parser also supports the native uv PEP 723 script-lock basename. +PARSERS = {"requirements.txt", "packages.lock.json", "uv.lock"} # osv-scanner 2.6.0 matches [[IgnoredVulns]] by id in every lockfile it scans (ShouldIgnore checks only the id and @@ -145,7 +147,7 @@ def python_pins(path, parser=None): includes, each read once (a shared or cyclic include is not read again). package is None for a line the guard cannot parse strictly, an include that names no file among them; version then holds the line. Nothing for the npm and NuGet lock formats, which cannot pin a PyPI package.""" - if path.name == "uv.lock": + if parser == "uv.lock" or path.name == "uv.lock": data = tomllib.loads(path.read_text(encoding="utf-8")) return [(path, canonical(p["name"]), p.get("version")) if "name" in p else (path, None, str(p)) for p in data.get("package", [])] @@ -452,6 +454,9 @@ def test_a_uv_lock_pin_is_read(self): self.assertEqual(scratch_findings({"uv.lock": lock}, scanned="uv.lock", parser=None), [("uv.lock", "nltk", "3.10.3", "GHSA-8mgp-746c-j5xp"), ("uv.lock", "setuptools", "80.10.2", "GHSA-h35f-9h28-mq5c")]) + self.assertEqual(scratch_findings({"worker.py.lock": lock}, scanned="worker.py.lock", parser="uv.lock"), + [("worker.py.lock", "nltk", "3.10.3", "GHSA-8mgp-746c-j5xp"), + ("worker.py.lock", "setuptools", "80.10.2", "GHSA-h35f-9h28-mq5c")]) def test_no_other_suppression_mechanism_bypasses_the_policy(self): config = tomllib.loads(CONFIG.read_text(encoding="utf-8")) diff --git a/tools/runtime-worker-evidence/checks.json b/tools/runtime-worker-evidence/checks.json index 7b9bb460f..62a8637c6 100644 --- a/tools/runtime-worker-evidence/checks.json +++ b/tools/runtime-worker-evidence/checks.json @@ -6,6 +6,12 @@ ], "scope": "Metadata/stream integration checks and publication integrity only; no new provider trial.", "attempts": [ + { + "command": "Native pre-push registry gate", + "exit_code": 1, + "returned_error": "Three new uv script lockfiles missing from .github/osv-scanner-lockfiles.json.", + "correction": "Registered all three with the source-verified native uv.lock override, preserved adversarial suppression checks, and ran native scanner acceptance; see osv-check.json." + }, { "command": "Native pre-commit gitleaks git --pre-commit --staged --redact", "exit_code": 1, diff --git a/tools/runtime-worker-evidence/osv-check.json b/tools/runtime-worker-evidence/osv-check.json new file mode 100644 index 000000000..36742ba76 --- /dev/null +++ b/tools/runtime-worker-evidence/osv-check.json @@ -0,0 +1,50 @@ +{ + "kind": "native_dependency_scan", + "recorded_at": "2026-09-30T16:39:29Z", + "evidence_scope": "Three newly introduced SDK uv script locks only; no whole-repository security or model quality claim.", + "source": { + "repository": "https://github.com/google/osv-scanner", + "tag": "v2.6.0", + "revision": "e840a6e8adb14b7777c78e26cfbf6e2abc1d1fc6", + "binary_asset": "osv-scanner_linux_amd64", + "published_and_downloaded_sha256": "ca69b3d3cd08f889a49dc0a383122f71cc528b83803671df5fd874d97485b108", + "native_version": "2.6.0", + "native_scalibr_version": "0.5.2", + "parser_source": "https://github.com/google/osv-scanner/blob/e840a6e8adb14b7777c78e26cfbf6e2abc1d1fc6/pkg/osvscanner/internal/scanners/lockfile.go#L62" + }, + "command": "rtk scan source --no-resolve --all-packages --format json --lockfile=uv.lock:examples/omniroute-codex-sdk/worker.py.lock --lockfile=uv.lock:examples/omniroute-codex-sdk/test_worker.py.lock --lockfile=uv.lock:examples/claude-runtime-sdk/worker.py.lock --output-file ", + "exit_code": 0, + "selected_actual_results": [ + { + "source_type": "lockfile", + "source_path": "examples/omniroute-codex-sdk/worker.py.lock", + "packages": 8, + "vulnerabilities": 0 + }, + { + "source_type": "lockfile", + "source_path": "examples/omniroute-codex-sdk/test_worker.py.lock", + "packages": 8, + "vulnerabilities": 0 + }, + { + "source_type": "lockfile", + "source_path": "examples/claude-runtime-sdk/worker.py.lock", + "packages": 32, + "vulnerabilities": 0 + } + ], + "native_returned_summary": "0 dirs visited, 3 inodes visited, 3 Extract calls", + "registry_correction": "The required pre-push tracked-lock inventory failed on these three paths. Added the supported uv.lock extractor override to the existing inventory and allowed parser set. Extended the existing suppression guard to recognize that explicit parser as well as literal uv.lock basenames.", + "local_guard_checks": { + "command": "rtk python3 -m unittest tests.test_osv_lockfile_coverage", + "exit_code": 0, + "returned_output": "Ran 30 tests in 0.234s\nOK", + "scope": "Authored registry and adversarial ignore-policy checks; forced script-lock test retains findings for deliberately vulnerable nltk/setuptools pins." + }, + "limitations": [ + "No exclusions, expiry rules, allowed advisory scopes or hooks were bypassed.", + "Package counts are per file, including duplicate locks and conditional package entries; they are not a unique installed-package count.", + "Scanner reports no known vulnerability in these locked inventories at this observation; future database updates and unscanned native/runtime dependencies remain separate." + ] +} From ef90678c199a53bb43344fedec2fbcd5b6bf5c58 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 13:31:45 -0400 Subject: [PATCH 09/14] test(foundation): retain native Claude to OmniRoute SDK acceptance --- .../omniroute-runtime-workers/experiment.json | 89 ++++++++++- .../2026-09-30-omniroute-runtime-workers.md | 21 ++- .../omniroute-claude-callsite-20260930.json | 139 ++++++++++++++++++ examples/omniroute-codex-sdk/README.md | 6 + manifests/evidence.json | 35 ++++- 5 files changed, 273 insertions(+), 17 deletions(-) create mode 100644 evidence/receipts/omniroute-claude-callsite-20260930.json diff --git a/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json b/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json index e2dea75cb..2b16896b4 100644 --- a/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json +++ b/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json @@ -55,7 +55,9 @@ "analytical-review", "bare-auth", "fixture-negative", - "fixture-positive" + "fixture-positive", + "claude-callsite", + "claude-sdk-child" ], "roles": [ "installer", @@ -93,6 +95,10 @@ { "path": "examples/omniroute-codex-sdk/test_worker.py", "sha256": "ea30d5bd0568f1e179e6460647ef61f2ca1ca025bda574f5f35a315eeee2ae2a" + }, + { + "path": "evidence/receipts/omniroute-claude-callsite-20260930.json", + "sha256": "a1dd584094ebb8aa1c58da0ac34d1d7b7ddb9fcf5e78b67732c7d3b3a0ba6ce3" } ] }, @@ -139,7 +145,9 @@ "Native Claude background Opus 5.5/Max ListAgents/SendMessage cooperation; stop only owned session after no final packet", "rtk proxy timeout --signal=TERM --kill-after=5s 240s claude -p --model claude-opus-5-5 --effort max --tools '' --strict-mcp-config --no-session-persistence --output-format json < ", "Native bare-mode analytical review negative control; no native authentication loading", - "rtk npm test (independent unchanged upstream fixture before and after the worker)" + "rtk npm test (independent unchanged upstream fixture before and after the worker)", + "rtk proxy timeout --signal=TERM --kill-after=5s 180s claude -p --model claude-opus-5-5 --effort max --tools 'Bash,Read,Skill' --allowedTools 'Bash Read Skill' --strict-mcp-config --max-turns 4 --no-session-persistence --verbose --output-format stream-json < ", + "Native Claude Bash calls rtk proxy uv run --locked --script examples/omniroute-codex-sdk/worker.py --workspace --codex-home --sandbox read-only --no-provider-retries --timeout 60 --request-id --native-result --prompt " ], "observations": [ { @@ -606,6 +614,68 @@ "total": 0, "native_retries": 0 } + }, + { + "id": "claude-native-callsite", + "task": "claude-callsite", + "role": "claude-peer", + "condition": "candidate", + "attempt": 1, + "command_index": 13, + "evidence_class": "model_task_execution", + "scope": "Native Claude coordinator dispatch to the primary SDK worker", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-claude-callsite-20260930.json", + "sha256": "a1dd584094ebb8aa1c58da0ac34d1d7b7ddb9fcf5e78b67732c7d3b3a0ba6ce3" + } + ], + "usage": { + "uncached_input": 6, + "cache_creation": 49127, + "cache_read": 92451, + "output": 2706, + "reasoning_in_output": 1805, + "total": 144290, + "native_retries": null + } + }, + { + "id": "sol-claude-dispatch", + "task": "claude-sdk-child", + "role": "sol-worker", + "condition": "candidate", + "attempt": 1, + "command_index": 14, + "evidence_class": "model_task_execution", + "scope": "Native Sol-Max SDK coding worker on the selected OmniRoute Responses lane", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-claude-callsite-20260930.json", + "sha256": "a1dd584094ebb8aa1c58da0ac34d1d7b7ddb9fcf5e78b67732c7d3b3a0ba6ce3" + } + ], + "usage": { + "uncached_input": 658, + "cache_creation": 0, + "cache_read": 30208, + "output": 139, + "reasoning_in_output": 27, + "total": 31005, + "native_retries": 0 + } } ], "failures_and_skips": [ @@ -650,7 +720,7 @@ "Draft reproduction text used incorrect Claude wrapper flag names. Both installed runner --help commands were checked before publication; the text now uses --cwd/--gateway/--skill/--setting-source, with Max effort configured natively by the runner. Actual attempted calls and results did not change.", "The first authored record validation failed because administrative task and role IDs were omitted from frozen_inputs. Those metadata declarations were corrected; no provider run or result changed.", "One arithmetic fixture and lifecycle acceptance; no universal SDK or model quality ranking.", - "Actual provider trials invoked the SDK from root, rather than through a Claude coordinator. Native project dispatch skill is supplied and structurally checked; its coordinator invocation remains unmeasured.", + "The original provider trials invoked the SDK directly. A subsequent native Claude 2.1.285 Opus 5.5/Max call discovered/read the project skill and invoked the Sol-Max SDK through Bash. This bounded read-only acceptance does not qualify other parent tools or optional MCP services.", "Native Codex SDK remains the incumbent. The separate frozen three-arm SDK gate remains unresolved.", "Native gateway requested/returned model labels are not backend attestation.", "All 136 skills are available in the owned project, with two bodies exercised; full role coverage and optional service acceptance remain incomplete.", @@ -658,7 +728,9 @@ "Complete provider usage, spending, remote cancellation and token savings remain unknown.", "Public record is sanitized selected actual return fields and independent observations; original private returned artifacts remain outside the checkout.", "Source/evaluation artifacts pin the final formatting-equivalent implementation; exact pre-format live worker bytes are retained in native commits named in the receipt.", - "The 136-skill native installation and check are separate from per-task quality. Upstream source suites, authored local fixtures and actual provider execution remain separate." + "The 136-skill native installation and check are separate from per-task quality. Upstream source suites, authored local fixtures and actual provider execution remain separate.", + "The new native Claude parent reports list-price cost and its own usage scope, separate from the external SDK child. The new child contributes 31,005 tokens once; distinct successful SDK threads now total 259,749. Parent usage is not added to that SDK total. Original independent transport reconciliation covers only the earlier 228,744 direct-trial tokens.", + "The first callsite record check rejected receipt kind native_model_e2e as an observation evidence_class. The published observation class was corrected to the validator-supported model_task_execution, matching retained provider trials; no run or receipt outcome changed. Independent review also corrected allowed Bash/Read/Skill versus actually invoked Read/Bash." ], "decision_and_scope": { "decision": "adopt_within_scope", @@ -666,11 +738,12 @@ "qualification_run_ids": [ "sol-fix", "sol-resume", - "sol-recovery" + "sol-recovery", + "sol-claude-dispatch" ] }, "rollback": "Stop the owned invocation/observer and use the retained native coordinator/runtime path. Keep recoverable private thread state for resume; no shared gateway or account rollback is needed because none was changed.", - "next_decision_changing_test": "Observe an actual native Claude coordinator invocation of the supplied project skill. Separately, a repaired Claude bridge must pass native skill/tool/edit/oracle/resume/cancel/recovery and truthful usage acceptance before promotion. Preserve the existing frozen three-arm SDK gate for any SDK-winner change.", + "next_decision_changing_test": "A repaired Claude bridge must pass native skill/tool/edit/oracle/resume/cancel/recovery and truthful usage acceptance before promotion. Extend task-specific role and optional-service coverage without indiscriminate loading. Preserve the existing frozen three-arm SDK gate for any SDK-winner change.", "usage_assessment": { "claim": "none", "coverage": "partial", @@ -689,7 +762,9 @@ "claude-review-timeout", "claude-bare-auth", "independent-negative", - "independent-positive" + "independent-positive", + "claude-native-callsite", + "sol-claude-dispatch" ], "coverage_artifact": { "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", diff --git a/docs/decisions/2026-09-30-omniroute-runtime-workers.md b/docs/decisions/2026-09-30-omniroute-runtime-workers.md index e5626eb4c..3dfb2c47f 100644 --- a/docs/decisions/2026-09-30-omniroute-runtime-workers.md +++ b/docs/decisions/2026-09-30-omniroute-runtime-workers.md @@ -122,10 +122,23 @@ universal quality claim follows from cache reuse. The scoped [convergence record](../../blueprints/convergence-practice/omniroute-runtime-workers/experiment.json) checks declared consistency, not truth or comparative superiority. -Actual provider acceptance invoked the SDK directly from the implementing -coordinator. The supplied Claude dispatch skill is structurally validated; a -native Claude coordinator invoking it remains a distinct unmeasured acceptance -step. Preserve the native sessions, existing SDK comparison gate and live +The first provider trials invoked the SDK directly. A subsequent bounded +[native Claude callsite check](../../evidence/receipts/omniroute-claude-callsite-20260930.json) +closed that remaining gap: native Claude 2.1.285, Opus 5.5/Max, discovered and read +the project dispatcher, invoked this official Sol-Max SDK worker through Bash, +and returned successfully in 47.696 seconds. The retained full native SDK result +shows exactly one unchanged test command with exit 0 and the expected marker. +The caller's compact summary only saw the marker; the original command exit and +test output provide the acceptance evidence. The worker ran 17.063 seconds and +reports 31,005 native tokens in a new thread. The successful SDK-thread total +now reaches 259,749, including the 228,744 direct-trial total; +the native Claude parent counters remain a separate scope. Its reported 0.4656502 +USD is native list-price accounting, not complete provider billing. This +read-only callsite allowed Bash/Read/Skill and actually called Read and Bash. +It does not qualify other coordinator tools or optional MCP services. Earlier +timeout records retain their outcomes; +the successful call does not promote the separate Claude SDK Devin bridge. +Preserve the native sessions, existing SDK comparison gate and live owner's shared files. Future bridge promotion requires successful native tools, skills, resume, cancellation/recovery and truthful usage on the selected route; an advertised model list or unchanged SDK test suite is insufficient. diff --git a/evidence/receipts/omniroute-claude-callsite-20260930.json b/evidence/receipts/omniroute-claude-callsite-20260930.json new file mode 100644 index 000000000..8a668d050 --- /dev/null +++ b/evidence/receipts/omniroute-claude-callsite-20260930.json @@ -0,0 +1,139 @@ +{ + "schema_version": 1, + "id": "omniroute-claude-callsite-20260930", + "kind": "native_model_e2e", + "component_ids": [ + "claude-code", + "codex", + "omniroute" + ], + "claim": "A native Claude Opus5.5/Max coordinator discovered and read the project dispatcher, invoked the official Sol-Max Codex SDK worker through native Bash, and the retained original shows one unchanged fixture test with exit0.", + "limitations": [ + "One bounded read-only callsite and existing arithmetic oracle; no universal quality or SDK winner claim.", + "Coordinator tool scope was Bash/Read/Skill for this acceptance; other coordinator tools and optional MCP services are not qualified.", + "Native Claude and external Codex SDK usage remain separate scopes; parent list-price cost is not complete provider billing.", + "The separate Claude SDK Devin bridge remains failed/unqualified; this native Claude-account coordinator run does not promote it.", + "Provider backend identity, overall task usage, failed/interrupted calls, remote cancellation and token savings remain unverified." + ], + "recorded_at": "2026-09-30T17:13:25Z", + "sources": { + "codex_sdk": { + "repository": "https://github.com/openai/codex", + "revision": "ff6aec96948b70d94983af2641a6b67c94faeff5", + "published_sdk_and_native_cli": "0.159.2", + "executed_worker_sha256": "8dfa1799dc2ce034548eb2581befe61bef480728cc541a451e960bb48decc651" + }, + "claude_skills": "https://code.claude.com/docs/en/skills", + "claude_native_cli_reported_version": "2.1.285", + "skill_sha256": "857a00f0c3f4088a20662f32f422b30c4697d0c267c0db1f9dbb95dfcbe39ce5", + "native_parent_private_original_sha256": "c09d98a296de6c549b501ef19dd1aa133802cd754ad66f1450a70c747d9eac3b", + "native_child_private_original_sha256": "676ec1926b648350b97271eb380589fe6d437a819de0b357ba39254cfb3a112a" + }, + "coordinator": { + "command": "rtk proxy timeout --signal=TERM --kill-after=5s 180s claude -p --model claude-opus-5-5 --effort max --tools 'Bash,Read,Skill' --allowedTools 'Bash Read Skill' --strict-mcp-config --max-turns 4 --no-session-persistence --verbose --output-format stream-json < ", + "exit_code": 0, + "requested_model": "claude-opus-5-5", + "requested_effort": "max", + "deadline_seconds": 180, + "subtype": "success", + "is_error": false, + "duration_ms": 47696, + "duration_api_ms": 27291, + "num_turns": 3, + "project_skill_in_native_init": true, + "project_skill_body_read": true, + "actual_tool_calls": [ + "Read", + "Bash" + ], + "native_init_tools": [ + "Bash", + "Read", + "Skill" + ], + "worker_invocation_count": 1, + "usage": { + "input_tokens": 6, + "cache_creation_input_tokens": 49127, + "cache_read_input_tokens": 92451, + "output_tokens": 2706, + "output_tokens_details": { + "thinking_tokens": 1805 + } + }, + "model_usage": { + "requested_and_reported_model": "claude-opus-5-5", + "inputTokens": 6, + "outputTokens": 2706, + "cacheReadInputTokens": 92451, + "cacheCreationInputTokens": 49127, + "thinkingTokens": 1805, + "contextWindow": 1000000, + "maxOutputTokens": 128000, + "reported_provider": "firstParty", + "costBasis": "list", + "costUSD": 0.4656502 + }, + "native_reported_cost_usd": 0.4656502, + "complete_billing_cost_usd": null, + "usage_scope": "Native Claude parent session; external SDK process is not part of its modelUsage. Count latest snapshot once and do not add thinking subset again.", + "routes_or_accounts_reconfigured": false + }, + "worker": { + "command": "rtk proxy uv run --locked --script examples/omniroute-codex-sdk/worker.py --workspace --codex-home --sandbox read-only --no-provider-retries --timeout 60 --request-id --native-result --prompt ", + "status": "completed", + "duration_ms": 17063, + "requested_model": "cx/gpt-6.1-sol-max", + "requested_effort": "max", + "provider": "omniroute_runtime", + "selected_gateway_port": 20128, + "independent_reverse_observer_used": false, + "native_runtime_version": "0.159.2", + "command_executions": 1, + "file_changes": 0, + "thread_relation": "New native SDK thread distinct from earlier direct trials", + "final_response": "CLAUDE_COORDINATOR_WORKER_ACCEPTED", + "native_usage": { + "last": { + "cacheWriteInputTokens": 0, + "cachedInputTokens": 15104, + "inputTokens": 15533, + "outputTokens": 43, + "reasoningOutputTokens": 27, + "totalTokens": 15576 + }, + "modelContextWindow": 258400, + "total": { + "cacheWriteInputTokens": 0, + "cachedInputTokens": 30208, + "inputTokens": 30866, + "outputTokens": 139, + "reasoningOutputTokens": 27, + "totalTokens": 31005 + } + }, + "usage_scope": "Latest cumulative native SDK thread snapshot; cached input and reasoning output are subsets. Last request is included in total.", + "actual_returned_oracle": { + "exitCode": 0, + "aggregatedOutput": "> test\n> node --test math.test.js\n✔ math.test.js (49.711303ms)\nℹ tests 1\nℹ suites 0\nℹ pass 1\nℹ fail 0\nℹ cancelled 0\nℹ skipped 0\nℹ todo 0\nℹ duration_ms 58.255161\n" + }, + "native_result_file_created": true + }, + "acceptance": { + "dispatcher_metadata_discovered": true, + "dispatcher_body_read": true, + "native_bash_invoked_sdk": true, + "actual_native_command_exit_verified": true, + "oracle_unchanged": true, + "worker_marker_verified": true, + "caller_summary_limit": "Compact worker stdout lacked per-command exit codes, so the Claude paragraph only saw a marker. Root verified exitCode0 and exact test output in the retained full native SDK artifact.", + "earlier_direct_sdk_successful_thread_tokens": 228744, + "new_disjoint_worker_thread_tokens": 31005, + "successful_sdk_threads_tokens_only": 259749, + "native_claude_parent_usage_added_to_sdk_total": false, + "complete_task_usage": null, + "complete_provider_billing": null, + "token_savings_claim": false, + "claude_sdk_bridge_promoted": false + } +} diff --git a/examples/omniroute-codex-sdk/README.md b/examples/omniroute-codex-sdk/README.md index 8afe1e6ee..c1cbb43af 100644 --- a/examples/omniroute-codex-sdk/README.md +++ b/examples/omniroute-codex-sdk/README.md @@ -32,6 +32,12 @@ the official SDK launch contract and the provider sources below. A source-backed caller recipe is distinct from observing an actual Claude `Bash` invocation; retain that native invocation before claiming Claude-side execution acceptance. +The [September30 native callsite receipt](../../evidence/receipts/omniroute-claude-callsite-20260930.json) +now retains that observation: native Opus5.5/Max discovered and read the project +dispatcher, called this worker through Bash, and the full native SDK result +shows one unchanged `npm test` command with exit0. This bounded read-only call +qualifies the caller path; the separate Claude SDK gateway bridge remains a trial. + The default endpoint is the selected loopback gateway at port 20128. An owned reverse observer can be supplied with `--base-url`; the worker never changes gateway compression engines or native coordinator configuration. The default diff --git a/manifests/evidence.json b/manifests/evidence.json index e3124ffad..c83ad78a5 100644 --- a/manifests/evidence.json +++ b/manifests/evidence.json @@ -1,6 +1,24 @@ { "schema_version": 1, "receipts": [ + { + "id": "omniroute-claude-callsite-20260930", + "kind": "native_model_e2e", + "component_ids": [ + "claude-code", + "codex", + "omniroute" + ], + "claim": "A native Claude Opus5.5/Max coordinator discovered and read the project dispatcher, invoked the official Sol-Max Codex SDK worker through native Bash, and the retained original shows one unchanged fixture test with exit0.", + "limitations": [ + "One bounded read-only callsite and existing arithmetic oracle; no universal quality or SDK winner claim.", + "Coordinator tool scope was Bash/Read/Skill for this acceptance; other coordinator tools and optional MCP services are not qualified.", + "Native Claude and external Codex SDK usage remain separate scopes; parent list-price cost is not complete provider billing.", + "The separate Claude SDK Devin bridge remains failed/unqualified; this native Claude-account coordinator run does not promote it.", + "Provider backend identity, overall task usage, failed/interrupted calls, remote cancellation and token savings remain unverified." + ], + "path": "evidence/receipts/omniroute-claude-callsite-20260930.json" + }, { "id": "omniroute-runtime-workers-20260930", "kind": "native_model_e2e", @@ -5546,8 +5564,8 @@ }, { "path": "blueprints/convergence-practice/omniroute-runtime-workers/experiment.json", - "sha256": "fbc8fb60192c306625a889e948bd2ca682dba9d0eeffd9bf768663b35679d324", - "bytes": 25944 + "sha256": "b95c7e1feecf8bdc2a9d315d1dd12551b1636f9ab68ed7ca0b18158efc84a17c", + "bytes": 29454 }, { "path": "blueprints/convergence-practice/protocol.json", @@ -14831,8 +14849,8 @@ }, { "path": "docs/decisions/2026-09-30-omniroute-runtime-workers.md", - "sha256": "1b9834cbcbff17ef74205d5093bc7e5b790b28cd5f9eeccff34fce4a049a6559", - "bytes": 9433 + "sha256": "ea1ea0bc6d9ab5cea0263cedf43cc392f65838b42546bdb15fbca20e7b0a6343", + "bytes": 10413 }, { "path": "docs/direct-results.md", @@ -43779,6 +43797,11 @@ "sha256": "0f6a0c171872cde9689d9d5f2ff60b881ae2328b96769dc78613f625cf9d1017", "bytes": 16128 }, + { + "path": "evidence/receipts/omniroute-claude-callsite-20260930.json", + "sha256": "a1dd584094ebb8aa1c58da0ac34d1d7b7ddb9fcf5e78b67732c7d3b3a0ba6ce3", + "bytes": 6238 + }, { "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e", @@ -44211,8 +44234,8 @@ }, { "path": "examples/omniroute-codex-sdk/README.md", - "sha256": "ec992256bb6b43262c3a7fe019fcfa9bd428bf04fd123e50b36b2ed7fa83c46a", - "bytes": 10099 + "sha256": "17316922e6eddf158641d3cf76294c9a4a6ffb43b33ee6bd5630a0e0b1091ab3", + "bytes": 10526 }, { "path": "examples/omniroute-codex-sdk/checks.json", From a6b21164e16754efd30edf513a1733ae046e9150 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 14:43:53 -0400 Subject: [PATCH 10/14] Add native metadata preflight to OmniRoute SDK worker --- examples/omniroute-codex-sdk/test_worker.py | 222 ++++++++++++++++++- examples/omniroute-codex-sdk/worker.py | 228 ++++++++++++++++++-- 2 files changed, 427 insertions(+), 23 deletions(-) diff --git a/examples/omniroute-codex-sdk/test_worker.py b/examples/omniroute-codex-sdk/test_worker.py index 13a658b1c..142a04396 100644 --- a/examples/omniroute-codex-sdk/test_worker.py +++ b/examples/omniroute-codex-sdk/test_worker.py @@ -11,21 +11,71 @@ codex-rs/core/tests/common/responses.rs::{sse,ev_response_created, ev_assistant_message,ev_completed}. The SDK and bundled native runtime are real; the loopback provider returns authored deterministic fixture responses. +The stdio MCP fixture derives from the same pin's +scripts/mcp_conformance/server.py::{ProtocolServer._handle_legacy,_list_tools, +run_stdio}. Its catalog responses are synthetic; no tool/model execution is +accepted by these discovery checks. """ import asyncio import json import os +import sys import tempfile import threading import unittest from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path +from types import SimpleNamespace import worker from openai_codex import AsyncCodex +MCP_FIXTURE = r''' +import json +import sys +import time +from pathlib import Path + +for line in sys.stdin: + message = json.loads(line) + method = message.get("method") + with Path(sys.argv[1]).open("a") as log: + log.write(json.dumps({"method": method}) + "\n") + if "id" not in message: + continue + if method == "initialize": + result = { + "protocolVersion": "2025-06-18", + "capabilities": {"tools": {}}, + "serverInfo": {"name": "native-fixture", "version": "1.0.0"}, + } + elif method == "tools/list": + if sys.argv[2] == "stall": + time.sleep(30) + if sys.argv[2] == "error": + print(json.dumps({"jsonrpc": "2.0", "id": message["id"], + "error": {"code": -32603, "message": "PRIVATE_TOOL_ERROR"}}), + flush=True) + continue + result = {"tools": [] if sys.argv[2] == "empty" else [{ + "name": "fixture_echo", "description": "PRIVATE_TOOL_DESCRIPTION", + "inputSchema": {"type": "object", "properties": {}}, + }]} + elif method == "resources/list": + result = {"resources": []} + elif method == "resources/templates/list": + result = {"resourceTemplates": []} + else: + print(json.dumps({"jsonrpc": "2.0", "id": message["id"], + "error": {"code": -32601, "message": "method not found"}}), + flush=True) + continue + print(json.dumps({"jsonrpc": "2.0", "id": message["id"], "result": result}), flush=True) +''' + + class FixtureGateway: def __init__(self, mode="complete"): self.mode = mode @@ -139,12 +189,20 @@ def args(self, gateway, *extra): ] ) - def run_worker(self, args, *, sdk_factory=AsyncCodex): + def run_worker(self, args, *, sdk_factory=None): events = [] instances, owned_pids = [], [] + class ObservedPreflightClient(worker.AsyncCodexClient): + async def initialize(self): + metadata = await super().initialize() + # Observation of this test's own process, never production API. + owned_pids.append(self._sync._proc.pid) + return metadata + def create_sdk(config): - instance = sdk_factory(config=config) + factory = sdk_factory or (ObservedPreflightClient if args.preflight else AsyncCodex) + instance = factory(config=config) instances.append(instance) return instance @@ -152,20 +210,62 @@ def observe(event): events.append(event) # Observation only: inspect the PID of this test's own SDK child. # Native source: sdk/python/src/openai_codex/client.py::_start_process. - process = instances[-1]._client._sync._proc + process = ( + instances[-1]._sync._proc + if args.preflight + else instances[-1]._client._sync._proc + ) if process is not None: owned_pids.append(process.pid) - result = asyncio.run( - worker.run_worker( + invocation = ( + worker.run_preflight(args, sdk_factory=create_sdk, on_event=observe) + if args.preflight + else worker.run_worker( args, "One bounded fixture task.", sdk_factory=create_sdk, on_event=observe ) ) + result = asyncio.run(invocation) for pid in owned_pids: with self.assertRaises(ProcessLookupError): os.kill(pid, 0) return result, events + def preflight_config(self, *, mcp_mode="complete", enabled=True): + script = self.project / "fixture_mcp.py" + script.write_text(MCP_FIXTURE) + log = self.project / "fixture_mcp_calls.jsonl" + skill = self.project / ".agents/skills/fixture-skill/SKILL.md" + skill.parent.mkdir(parents=True, exist_ok=True) + skill.write_text( + "---\nname: fixture-skill\ndescription: PRIVATE_SKILL_DESCRIPTION\n---\n" + "PRIVATE_SKILL_BODY\n" + ) + role = self.home / "fixture-verifier.toml" + role.write_text( + f"model = {json.dumps(worker.DEFAULT_MODEL)}\n" + 'model_reasoning_effort = "max"\n' + ) + config = ( + "[mcp_servers.fixture-mcp]\n" + f"command = {json.dumps(sys.executable)}\n" + f"args = {json.dumps([str(script), str(log), mcp_mode])}\n" + f"enabled = {str(enabled).lower()}\n" + "startup_timeout_sec = 5.0\n" + "[agents]\n" + "enabled = true\n" + "max_concurrent_threads_per_session = 3\n" + f"default_subagent_model = {json.dumps(worker.DEFAULT_MODEL)}\n" + 'default_subagent_reasoning_effort = "max"\n' + "[agents.fixture-verifier]\n" + 'description = "PRIVATE_ROLE_DESCRIPTION"\n' + f"config_file = {json.dumps(str(role))}\n" + f"[projects.{json.dumps(str(self.project))}]\n" + 'trust_level = "trusted"\n' + ) + (self.home / "config.toml").write_text(config) + return log + def assert_accepted(self, result): self.assertEqual(result["status"], "completed", result) self.assertEqual(result["cleanup_status"], "closed", result) @@ -280,6 +380,118 @@ def test_native_artifact_is_private_and_never_overwritten(self): self.assertEqual(duplicate["error_type"], "FileExistsError") self.assertEqual(destination.read_bytes(), retained) + def test_preflight_discovers_native_mcp_skill_and_roles_without_inference(self): + log = self.preflight_config() + with FixtureGateway() as gateway: + result, events = self.run_worker( + self.args( + gateway, + "--preflight", + "--require-mcp", + "fixture-mcp", + "--require-skill", + "fixture-skill", + ) + ) + self.assertEqual(result["status"], "ready", result) + self.assertEqual(result["cleanup_status"], "closed", result) + self.assertFalse(result["model_inference_submitted"]) + self.assertFalse(gateway.requests) + self.assertNotIn("thread_id", result) + self.assertIsNone(result["usage"]) + self.assertEqual(result["evidence_scope"], "native_catalog_discovery") + self.assertEqual(result["native_runtime"]["version"], worker.SDK_VERSION) + self.assertEqual(result["native_runtime"]["metadata_source"], "userAgent") + self.assertEqual(events[0]["event"], "preflight_discovered") + server = next(s for s in result["mcp_servers"] if s["name"] == "fixture-mcp") + self.assertTrue(server["configured"]) + self.assertTrue(server["enabled"]) + self.assertIsNone(server["runtime_status"]) + self.assertFalse(server["tools_error"]) + self.assertIn("fixture_echo", server["tool_names"]) + self.assertIn( + {"name": "fixture-skill", "enabled": True, "scope": "repo"}, result["skills"] + ) + self.assertIn( + {"name": "fixture-verifier"}, + result["configured_roles"], + ) + self.assertEqual(result["agent_defaults"]["max_concurrent_threads_per_session"], 3) + self.assertEqual(result["agent_defaults"]["default_subagent_model"], worker.DEFAULT_MODEL) + self.assertEqual(result["agent_defaults"]["default_subagent_reasoning_effort"], "max") + serialized = json.dumps([result, events]) + for private in [str(self.project), str(self.home), "PRIVATE_", "config.toml"]: + self.assertNotIn(private, serialized) + methods = [json.loads(line)["method"] for line in log.read_text().splitlines()] + self.assertIn("initialize", methods) + self.assertIn("tools/list", methods) + self.assertNotIn("tools/call", methods) + + def test_preflight_missing_mcp_and_skill_fail_without_inference(self): + with FixtureGateway() as gateway: + result, _ = self.run_worker( + self.args( + gateway, + "--preflight", + "--require-mcp", + "missing-mcp", + "--require-skill", + "missing-skill", + ) + ) + self.assertEqual(result["status"], "unavailable", result) + self.assertEqual(result["requirements"]["unavailable_mcp"], ["missing-mcp"]) + self.assertEqual(result["requirements"]["unavailable_skills"], ["missing-skill"]) + self.assertFalse(result["model_inference_submitted"]) + self.assertFalse(gateway.requests) + self.assertEqual(result["cleanup_status"], "closed") + + def test_preflight_disabled_empty_and_error_mcp_catalogs_fail_requirement(self): + with FixtureGateway() as gateway: + for mode, enabled in [("complete", False), ("empty", True), ("error", True)]: + with self.subTest(mode=mode, enabled=enabled): + self.preflight_config(mcp_mode=mode, enabled=enabled) + result, _ = self.run_worker( + self.args(gateway, "--preflight", "--require-mcp", "fixture-mcp") + ) + self.assertEqual(result["status"], "unavailable", result) + self.assertEqual( + result["requirements"]["unavailable_mcp"], ["fixture-mcp"] + ) + self.assertNotIn("PRIVATE_", json.dumps(result)) + self.assertFalse(result["model_inference_submitted"]) + self.assertFalse(gateway.requests) + self.assertEqual(result["cleanup_status"], "closed") + + def test_preflight_deadline_closes_without_inference(self): + self.preflight_config(mcp_mode="stall") + with FixtureGateway() as gateway: + result, _ = self.run_worker( + self.args(gateway, "--preflight", "--timeout", "1") + ) + self.assertEqual(result["status"], "deadline_exceeded", result) + self.assertEqual(result["phase"], "mcp_discovery") + self.assertEqual(result["cleanup_status"], "closed") + self.assertFalse(result["model_inference_submitted"]) + self.assertFalse(gateway.requests) + + def test_preflight_requirements_are_explicit_and_do_not_change_turns(self): + with FixtureGateway() as gateway: + with self.assertRaises(SystemExit): + self.args(gateway, "--require-mcp", "fixture-mcp") + with self.assertRaises(SystemExit): + self.args(gateway, "--require-skill", "fixture-skill") + with self.assertRaises(SystemExit): + self.args(gateway, "--preflight", "--resume", "fixture-thread") + + def test_explicit_wrong_runtime_version_is_not_replaced_by_user_agent(self): + metadata = SimpleNamespace( + serverInfo=SimpleNamespace(name="native-fixture", version="0.0.0"), + userAgent="native-fixture/0.159.2", + ) + with self.assertRaises(RuntimeError): + worker.native_runtime(metadata) + if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/examples/omniroute-codex-sdk/worker.py b/examples/omniroute-codex-sdk/worker.py index bb493b8bf..cfc41bd36 100644 --- a/examples/omniroute-codex-sdk/worker.py +++ b/examples/omniroute-codex-sdk/worker.py @@ -5,11 +5,13 @@ # "openai-codex==0.159.2", # ] # /// -"""One native Codex SDK turn through an invocation-scoped OmniRoute provider. +"""One native Codex SDK turn, or metadata preflight, through OmniRoute. Derived from openai/codex rust-v0.159.2, commit ff6aec96948b70d94983af2641a6b67c94faeff5, sdk/python/examples/{01,05,14}_* -and sdk/python/src/openai_codex/{api,client,_run}.py. See README.md for sources. +and sdk/python/src/openai_codex/{api,client,_run,async_client}.py. Preflight uses +the public typed requests in generated/v2_all.py and the native app-server +request_processors/mcp_processor.rs. See README.md for sources. """ from __future__ import annotations @@ -26,6 +28,12 @@ from urllib.parse import urlsplit from openai_codex import ApprovalMode, AsyncCodex, CodexConfig, Sandbox +from openai_codex.async_client import AsyncCodexClient +from openai_codex.generated.v2_all import ( + ConfigReadResponse, + ListMcpServerStatusResponse, + SkillsListResponse, +) from openai_codex.types import ReasoningEffort SDK_VERSION = "0.159.2" @@ -126,14 +134,8 @@ def emit(value: dict) -> None: print(json.dumps(value, ensure_ascii=False, separators=(",", ":")), flush=True) -async def run_worker( - args: argparse.Namespace, prompt: str, *, sdk_factory=AsyncCodex, on_event=emit -) -> dict: - """Use native start/resume/turn/interrupt/close, with one overall deadline.""" - codex = sdk_factory(config=runtime_config(args)) - turn = None - phase = "initialize" - record = { +def initial_record(args: argparse.Namespace) -> dict: + return { "request_id": args.request_id, "requested_model": args.model, "requested_effort": "max", @@ -143,13 +145,180 @@ async def run_worker( "usage_scope": None, "usage": None, } + + +def native_runtime(metadata) -> dict: + # Match the pinned SDK's _initialize_metadata.py normalization using public + # response fields. Low-level initialize() returns serverInfo=None on 0.159.2. + server = metadata.serverInfo + name = (server.name or "").strip() if server is not None else "" + version = (server.version or "").strip() if server is not None else "" + source = "serverInfo" + if not name or not version: + source = "userAgent" + user_agent = (metadata.userAgent or "").strip() + if "/" in user_agent: + parsed_name, parsed_version = user_agent.split("/", 1) + else: + parts = user_agent.split(maxsplit=1) + parsed_name = parts[0] if parts else "" + parsed_version = parts[1] if len(parts) == 2 else "" + name = name or parsed_name.strip() + version = version or parsed_version.strip() + if not name or not version or version.split()[0] != SDK_VERSION: + raise RuntimeError("native runtime does not match the qualified SDK pin") + return {"name": name, "version": version.split()[0], "metadata_source": source} + + +async def run_preflight( + args: argparse.Namespace, *, sdk_factory=AsyncCodexClient, on_event=emit +) -> dict: + """Inspect native catalogs without a thread, model turn or tool call. + + The public low-level client owns a separate app-server for this invocation. + Native 0.159.2 ignores CLI profile selection in app-server mode; configuration + comes from CODEX_HOME/config.toml and supported config_overrides instead. + """ + codex = sdk_factory(config=runtime_config(args)) + phase = "initialize" + record = { + **initial_record(args), + "preflight": True, + "evidence_scope": "native_catalog_discovery", + } + try: + async with asyncio.timeout(args.timeout): + await codex.start() + record["native_runtime"] = native_runtime(await codex.initialize()) + phase = "configuration_read" + effective = await codex.request( + "config/read", + {"cwd": str(args.workspace.resolve()), "includeLayers": False}, + response_model=ConfigReadResponse, + ) + if effective.config.model != args.model or effective.config.model_provider != PROVIDER: + raise RuntimeError("native configuration did not retain the requested routing") + # Config's public extra fields carry native MCP/agent configuration. + # Keep only names, enabled flags and routing metadata, never the + # full configuration, environment values, descriptions or paths. + extra = effective.config.model_extra or {} + configured_mcp = extra.get("mcp_servers") or {} + agents = extra.get("agents") or {} + record["agent_defaults"] = { + key: agents[key] + for key in ( + "enabled", + "max_concurrent_threads_per_session", + "default_subagent_model", + "default_subagent_reasoning_effort", + ) + if key in agents + } + record["configured_roles"] = [ + {"name": name} + for name, role in sorted(agents.items()) + if isinstance(role, dict) + ] + phase = "mcp_discovery" + servers, cursor, seen_cursors = [], None, set() + while True: + page = await codex.request( + "mcpServerStatus/list", + {"cursor": cursor, "limit": 100, "detail": "full"}, + response_model=ListMcpServerStatusResponse, + ) + for server in page.data: + configured = configured_mcp.get(server.name) + servers.append( + { + "name": server.name, + "configured": isinstance(configured, dict), + "enabled": isinstance(configured, dict) + and configured.get("enabled", True) is True, + # Without threadId, native status is null. Preserve + # unknown; catalog discovery is not tool execution. + "runtime_status": server.runtime_status.value + if server.runtime_status is not None + else None, + "auth_status": server.auth_status.value, + "tool_names": sorted(server.tools), + "tools_error": server.tools_error is not None, + } + ) + cursor = page.next_cursor + if cursor is None: + break + if cursor in seen_cursors: + raise RuntimeError("native MCP pagination did not advance") + seen_cursors.add(cursor) + record["mcp_servers"] = sorted(servers, key=lambda server: server["name"]) + phase = "skills_discovery" + listed = await codex.request( + "skills/list", + {"cwds": [str(args.workspace.resolve())], "forceReload": True}, + response_model=SkillsListResponse, + ) + record["skills"] = [ + {"name": skill.name, "enabled": skill.enabled, "scope": skill.scope.value} + for entry in listed.data + for skill in entry.skills + ] + record["skill_error_count"] = sum(len(entry.errors) for entry in listed.data) + available_mcp = { + server["name"] + for server in servers + if server["configured"] + and server["enabled"] + and server["tool_names"] + and not server["tools_error"] + } + available_skills = { + skill["name"] for skill in record["skills"] if skill["enabled"] + } + record["requirements"] = { + "mcp": args.require_mcp, + "skills": args.require_skill, + "unavailable_mcp": sorted(set(args.require_mcp) - available_mcp), + "unavailable_skills": sorted(set(args.require_skill) - available_skills), + } + on_event({"event": "preflight_discovered", **record}) + phase = "require_capabilities" + record["status"] = ( + "unavailable" + if record["requirements"]["unavailable_mcp"] + or record["requirements"]["unavailable_skills"] + else "ready" + ) + except (TimeoutError, asyncio.CancelledError) as exc: + record.update( + status="deadline_exceeded" if isinstance(exc, TimeoutError) else "cancelled", + phase=phase, + ) + if isinstance(exc, asyncio.CancelledError): + raise + except Exception as exc: + record.update(status="failed", error_type=type(exc).__name__, phase=phase) + finally: + try: + await asyncio.wait_for(codex.close(), CLEANUP_TIMEOUT) + record["cleanup_status"] = "closed" + except Exception as exc: + record.update(status="cleanup_failed", cleanup_status=type(exc).__name__) + return record + + +async def run_worker( + args: argparse.Namespace, prompt: str, *, sdk_factory=AsyncCodex, on_event=emit +) -> dict: + """Use native start/resume/turn/interrupt/close, with one overall deadline.""" + codex = sdk_factory(config=runtime_config(args)) + turn = None + phase = "initialize" + record = initial_record(args) try: async with asyncio.timeout(args.timeout): await codex.__aenter__() - server = codex.metadata.serverInfo - if server is None or server.version.split()[0] != SDK_VERSION: - raise RuntimeError("native runtime does not match the qualified SDK pin") - record["native_runtime"] = {"name": server.name, "version": server.version} + record["native_runtime"] = native_runtime(codex.metadata) options = { "cwd": str(args.workspace.resolve()), "model": args.model, @@ -217,6 +386,21 @@ def parse_args(argv=None) -> argparse.Namespace: parser.add_argument("--workspace", type=Path, default=Path.cwd()) parser.add_argument("--prompt", default="-", help="one bounded task, or - to read stdin") parser.add_argument("--resume", help="native thread id from an earlier invocation") + parser.add_argument( + "--preflight", action="store_true", help="inspect native catalogs without model inference" + ) + parser.add_argument( + "--require-mcp", + action="append", + default=[], + help="preflight requires this enabled server's native tool catalog; repeatable", + ) + parser.add_argument( + "--require-skill", + action="append", + default=[], + help="preflight requires this enabled native skill name; repeatable", + ) parser.add_argument( "--model", default=DEFAULT_MODEL, @@ -264,16 +448,24 @@ def parse_args(argv=None) -> argparse.Namespace: parser.error("codex-home must be an existing private state directory") if not args.model.strip(): parser.error("model must be nonempty") + if (args.require_mcp or args.require_skill) and not args.preflight: + parser.error("require-mcp and require-skill require --preflight") + if any(not name.strip() for name in [*args.require_mcp, *args.require_skill]): + parser.error("required capability names must be nonempty") + if args.preflight and (args.resume or args.native_result): + parser.error("preflight cannot resume a thread or retain turn items") return args def main() -> int: args = parse_args() - prompt = sys.stdin.read() if args.prompt == "-" else args.prompt - if not prompt.strip(): + prompt = "" + if not args.preflight: + prompt = sys.stdin.read() if args.prompt == "-" else args.prompt + if not args.preflight and not prompt.strip(): raise SystemExit("prompt must contain a bounded task") try: - result = asyncio.run(run_worker(args, prompt)) + result = asyncio.run(run_preflight(args) if args.preflight else run_worker(args, prompt)) except KeyboardInterrupt: emit( { @@ -285,7 +477,7 @@ def main() -> int: ) return 130 emit({"event": "result", **result}) - return 0 if result["status"] == "completed" else 2 + return 0 if result["status"] in {"completed", "ready"} else 2 if __name__ == "__main__": From 44b0fa94357498b51afdbbb2958219cec7d14ce4 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 14:57:01 -0400 Subject: [PATCH 11/14] Keep native preflight CLI receipts compact by default --- examples/omniroute-codex-sdk/test_worker.py | 67 +++++++++++++++++++++ examples/omniroute-codex-sdk/worker.py | 64 +++++++++++++++++--- 2 files changed, 122 insertions(+), 9 deletions(-) diff --git a/examples/omniroute-codex-sdk/test_worker.py b/examples/omniroute-codex-sdk/test_worker.py index 142a04396..2ab04fb68 100644 --- a/examples/omniroute-codex-sdk/test_worker.py +++ b/examples/omniroute-codex-sdk/test_worker.py @@ -18,6 +18,8 @@ """ import asyncio +import contextlib +import io import json import os import sys @@ -27,6 +29,7 @@ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path from types import SimpleNamespace +from unittest.mock import patch import worker from openai_codex import AsyncCodex @@ -400,6 +403,14 @@ def test_preflight_discovers_native_mcp_skill_and_roles_without_inference(self): self.assertNotIn("thread_id", result) self.assertIsNone(result["usage"]) self.assertEqual(result["evidence_scope"], "native_catalog_discovery") + self.assertEqual( + result["effective_config"], + { + "model": worker.DEFAULT_MODEL, + "model_provider": worker.PROVIDER, + "model_reasoning_effort": "max", + }, + ) self.assertEqual(result["native_runtime"]["version"], worker.SDK_VERSION) self.assertEqual(result["native_runtime"]["metadata_source"], "userAgent") self.assertEqual(events[0]["event"], "preflight_discovered") @@ -483,6 +494,62 @@ def test_preflight_requirements_are_explicit_and_do_not_change_turns(self): self.args(gateway, "--require-skill", "fixture-skill") with self.assertRaises(SystemExit): self.args(gateway, "--preflight", "--resume", "fixture-thread") + with self.assertRaises(SystemExit): + self.args(gateway, "--catalog-details") + + def test_preflight_cli_emits_one_compact_result_or_explicit_catalog_details(self): + self.preflight_config() + extra_skill = self.project / ".agents/skills/unrequired-skill/SKILL.md" + extra_skill.parent.mkdir(parents=True) + extra_skill.write_text( + "---\nname: unrequired-skill\ndescription: PRIVATE_UNUSED_DESCRIPTION\n---\n" + "PRIVATE_UNUSED_BODY\n" + ) + with FixtureGateway() as gateway: + argv = [ + worker.__file__, + "--workspace", str(self.project), + "--codex-home", str(self.home), + "--base-url", gateway.url, + "--timeout", "15", + "--preflight", + "--require-mcp", "fixture-mcp", + "--require-skill", "fixture-skill", + ] + for detailed in [False, True]: + with self.subTest(catalog_details=detailed): + stdout = io.StringIO() + with patch.object(sys, "argv", argv + (["--catalog-details"] if detailed else [])): + with contextlib.redirect_stdout(stdout): + exit_code = worker.main() + lines = stdout.getvalue().splitlines() + self.assertEqual(exit_code, 0) + self.assertEqual(len(lines), 1, stdout.getvalue()) + result = json.loads(lines[0]) + self.assertEqual(result["event"], "result") + self.assertEqual(result["status"], "ready") + self.assertEqual(result["requirements"]["unavailable_mcp"], []) + self.assertEqual(result["requirements"]["unavailable_skills"], []) + self.assertEqual(result["effective_config"]["model"], worker.DEFAULT_MODEL) + self.assertEqual(result["cleanup_status"], "closed") + self.assertFalse(result["model_inference_submitted"]) + self.assertNotIn("PRIVATE_", lines[0]) + if detailed: + self.assertIn("fixture_echo", result["mcp_servers"][0]["tool_names"]) + self.assertIn("unrequired-skill", [s["name"] for s in result["skills"]]) + else: + server = result["mcp_servers"][0] + self.assertEqual(server["tool_count"], 1) + self.assertTrue(server["catalog_ready"]) + self.assertNotIn("tool_names", server) + self.assertEqual(result["skills"]["required"], {"fixture-skill": True}) + self.assertGreaterEqual(result["skills"]["enabled_count"], 2) + self.assertGreaterEqual( + result["skills"]["total_count"], result["skills"]["enabled_count"] + ) + self.assertNotIn("unrequired-skill", lines[0]) + self.assertNotIn("fixture_echo", lines[0]) + self.assertFalse(gateway.requests) def test_explicit_wrong_runtime_version_is_not_replaced_by_user_agent(self): metadata = SimpleNamespace( diff --git a/examples/omniroute-codex-sdk/worker.py b/examples/omniroute-codex-sdk/worker.py index cfc41bd36..9173bde32 100644 --- a/examples/omniroute-codex-sdk/worker.py +++ b/examples/omniroute-codex-sdk/worker.py @@ -170,8 +170,43 @@ def native_runtime(metadata) -> dict: return {"name": name, "version": version.split()[0], "metadata_source": source} +def mcp_catalog_ready(server: dict) -> bool: + return bool( + server["configured"] + and server["enabled"] + and server["tool_names"] + and not server["tools_error"] + ) + + +def preflight_output(record: dict, *, catalog_details: bool = False) -> dict: + """Keep CLI receipts compact; explicit diagnostics retain native catalogs.""" + if catalog_details: + return record + compact = dict(record) + if "mcp_servers" in record: + compact["mcp_servers"] = [ + { + **{key: value for key, value in server.items() if key != "tool_names"}, + "tool_count": len(server["tool_names"]), + "catalog_ready": mcp_catalog_ready(server), + } + for server in record["mcp_servers"] + ] + if "skills" in record: + available = {skill["name"] for skill in record["skills"] if skill["enabled"]} + compact["skills"] = { + "total_count": len(record["skills"]), + "enabled_count": sum(skill["enabled"] for skill in record["skills"]), + "required": { + name: name in available for name in record["requirements"]["skills"] + }, + } + return compact + + async def run_preflight( - args: argparse.Namespace, *, sdk_factory=AsyncCodexClient, on_event=emit + args: argparse.Namespace, *, sdk_factory=AsyncCodexClient, on_event=None ) -> dict: """Inspect native catalogs without a thread, model turn or tool call. @@ -196,6 +231,13 @@ async def run_preflight( {"cwd": str(args.workspace.resolve()), "includeLayers": False}, response_model=ConfigReadResponse, ) + record["effective_config"] = { + "model": effective.config.model, + "model_provider": effective.config.model_provider, + "model_reasoning_effort": effective.config.model_reasoning_effort.value + if effective.config.model_reasoning_effort is not None + else None, + } if effective.config.model != args.model or effective.config.model_provider != PROVIDER: raise RuntimeError("native configuration did not retain the requested routing") # Config's public extra fields carry native MCP/agent configuration. @@ -265,12 +307,7 @@ async def run_preflight( ] record["skill_error_count"] = sum(len(entry.errors) for entry in listed.data) available_mcp = { - server["name"] - for server in servers - if server["configured"] - and server["enabled"] - and server["tool_names"] - and not server["tools_error"] + server["name"] for server in servers if mcp_catalog_ready(server) } available_skills = { skill["name"] for skill in record["skills"] if skill["enabled"] @@ -281,7 +318,8 @@ async def run_preflight( "unavailable_mcp": sorted(set(args.require_mcp) - available_mcp), "unavailable_skills": sorted(set(args.require_skill) - available_skills), } - on_event({"event": "preflight_discovered", **record}) + if on_event is not None: + on_event({"event": "preflight_discovered", **record}) phase = "require_capabilities" record["status"] = ( "unavailable" @@ -389,6 +427,11 @@ def parse_args(argv=None) -> argparse.Namespace: parser.add_argument( "--preflight", action="store_true", help="inspect native catalogs without model inference" ) + parser.add_argument( + "--catalog-details", + action="store_true", + help="preflight includes complete sanitized tool and skill catalogs in its result", + ) parser.add_argument( "--require-mcp", action="append", @@ -450,6 +493,8 @@ def parse_args(argv=None) -> argparse.Namespace: parser.error("model must be nonempty") if (args.require_mcp or args.require_skill) and not args.preflight: parser.error("require-mcp and require-skill require --preflight") + if args.catalog_details and not args.preflight: + parser.error("catalog-details requires --preflight") if any(not name.strip() for name in [*args.require_mcp, *args.require_skill]): parser.error("required capability names must be nonempty") if args.preflight and (args.resume or args.native_result): @@ -476,7 +521,8 @@ def main() -> int: } ) return 130 - emit({"event": "result", **result}) + output = preflight_output(result, catalog_details=args.catalog_details) if args.preflight else result + emit({"event": "result", **output}) return 0 if result["status"] in {"completed", "ready"} else 2 From 007d40dd549463aa8a0d5bdf45c0dde4e4d52478 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 15:52:14 -0400 Subject: [PATCH 12/14] feat(foundation): qualify enhanced native OmniRoute worker graph --- .../skills/omniroute-runtime-worker/SKILL.md | 8 +- .../experiment.json | 777 ++++++++++++++++++ .../omniroute-runtime-workers/experiment.json | 9 +- .../deadline300-judge-oracle-output.txt | 11 + .../initial-runtime-worker.yaml.txt | 22 + .../initial-runtime.config.template.toml.txt | 51 ++ .../post-env-import-runtime-worker.yaml.txt | 29 + .../repaired-judge-oracle-output.txt | 11 + .../pre-enhancement-dispatcher.md | 42 + .../pre-enhancement-test_worker.py.txt | 285 +++++++ .../pre-enhancement-worker.py.txt | 292 +++++++ ...niroute-runtime-enhancements-20260930.json | 731 ++++++++++++++++ examples/omniroute-codex-sdk/README.md | 5 + .../omniroute-codex-sdk/acceptance-plan.json | 27 + .../agents/runtime-judge.toml | 11 + examples/omniroute-codex-sdk/enhancements.md | 150 ++++ examples/omniroute-codex-sdk/rerun-plan.json | 24 + .../omniroute-codex-sdk/runtime-worker.yaml | 29 + .../runtime.config.template.toml | 57 ++ manifests/evidence.json | 124 ++- 20 files changed, 2679 insertions(+), 16 deletions(-) create mode 100644 blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json create mode 100644 evidence/artifacts/omniroute-runtime-enhancements-20260930/deadline300-judge-oracle-output.txt create mode 100644 evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime-worker.yaml.txt create mode 100644 evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime.config.template.toml.txt create mode 100644 evidence/artifacts/omniroute-runtime-enhancements-20260930/post-env-import-runtime-worker.yaml.txt create mode 100644 evidence/artifacts/omniroute-runtime-enhancements-20260930/repaired-judge-oracle-output.txt create mode 100644 evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-dispatcher.md create mode 100644 evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-test_worker.py.txt create mode 100644 evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-worker.py.txt create mode 100644 evidence/receipts/omniroute-runtime-enhancements-20260930.json create mode 100644 examples/omniroute-codex-sdk/acceptance-plan.json create mode 100644 examples/omniroute-codex-sdk/agents/runtime-judge.toml create mode 100644 examples/omniroute-codex-sdk/enhancements.md create mode 100644 examples/omniroute-codex-sdk/rerun-plan.json create mode 100644 examples/omniroute-codex-sdk/runtime-worker.yaml create mode 100644 examples/omniroute-codex-sdk/runtime.config.template.toml diff --git a/.claude/skills/omniroute-runtime-worker/SKILL.md b/.claude/skills/omniroute-runtime-worker/SKILL.md index bcd21d94d..dafe28855 100644 --- a/.claude/skills/omniroute-runtime-worker/SKILL.md +++ b/.claude/skills/omniroute-runtime-worker/SKILL.md @@ -9,7 +9,9 @@ Bash tool. The primary route is `cx/gpt-6.1-sol-max`, with native Max effort. The coordinator retains its native Claude account and model route. Give a writing worker its own worktree, bounded file ownership, an executable -acceptance condition and an existing private Codex home. Tell it other workers +acceptance condition and a configured private Codex home. For MCP, native agents +or automation, follow `examples/omniroute-codex-sdk/enhancements.md` and pass its +readiness check before dispatch. Tell it other workers are present and that it must preserve their edits. Feed the task on stdin: ```sh @@ -24,7 +26,9 @@ Use the selected gateway's native Responses lane at loopback port 20128. Keep native caches, tools and project skill discovery intact; load only task-relevant skill bodies. Install selected skills through the existing runtime-worker skill recipe, rather than importing the entire catalog into the task prompt. Optional -MCP services require their own configuration and acceptance. +MCP services use their native configuration and task-specific readiness checks. +Use the coordinator's selected native workflow roles for research, implementation +and verification, and the bounded Dagu graph when the task needs automation. Keep returned thread IDs private and use `--resume` for continuation. The latest thread usage snapshot includes previous turns; count it once. A deadline invokes diff --git a/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json b/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json new file mode 100644 index 000000000..acb4f7f6f --- /dev/null +++ b/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json @@ -0,0 +1,777 @@ +{ + "schema_version": 1, + "kind": "convergence_experiment", + "status": "observed", + "lane": "native-agent-engineering", + "task_and_failure": "Enhance the native OmniRoute SDK worker with on-demand skills, selected MCP tools, bounded native roles and Dagu readiness/work execution. Preserve environment/model-validation/deadline failures and qualify the repaired integration only.", + "primary_sources_and_pins": [ + { + "url": "https://github.com/openai/codex/tree/ff6aec96948b70d94983af2641a6b67c94faeff5", + "revision": "ff6aec96948b70d94983af2641a6b67c94faeff5" + }, + { + "url": "https://github.com/mksglu/context-mode/tree/589d8214d56740a28b5f7bf63167743d586b0b40", + "revision": "589d8214d56740a28b5f7bf63167743d586b0b40" + }, + { + "url": "https://github.com/oraios/serena/tree/c6fbd1c5932df2494ffa0020af5a9fbe80b82143", + "revision": "c6fbd1c5932df2494ffa0020af5a9fbe80b82143" + }, + { + "url": "https://github.com/dagucloud/dagu/tree/58fed633d58c1dd1319091fdb2c2f6158ecfa053", + "revision": "58fed633d58c1dd1319091fdb2c2f6158ecfa053" + }, + { + "url": "https://github.com/mitmproxy/mitmproxy/tree/6c09d56e4c29a92f5ad01b03199977584b8ea14f", + "revision": "6c09d56e4c29a92f5ad01b03199977584b8ea14f" + }, + { + "url": "https://github.com/diegosouzapw/OmniRoute/tree/c1e30b7676975feb298b49eff6ff58923c04b89e", + "revision": "c1e30b7676975feb298b49eff6ff58923c04b89e" + } + ], + "discovery_provenance": [ + "Installed native clients/help and typed configuration, version-matched pinned upstream source and official documentation; existing maintained integration recipes reused.", + "Sol worker implemented only the SDK example/tests in a separate worktree; source-derived native configuration and graph kept outside live owners' shared paths.", + "Astra/Max reviewed consequential architecture, initialization failure after one Sol repair, alias validation ordering, Dagu environment filtering and original final execution artifacts. Corrections remain in the receipt." + ], + "license_and_compatibility": "Reuse the maintained native Codex SDK/app-server, selected Context Mode and Serena stdio entries, pinned Dagu graph/env format, RTK proxy and existing mitmproxy observer. No custom orchestration loop, global auth migration, gateway change or trading operation.", + "baseline_and_candidate": { + "baseline": "Previously accepted native Sol-Max SDK lifecycle and historical Claude-to-SDK callsite, without this enhancement contract.", + "candidate": "Scoped skill/MCP/native Astra judge readiness and bounded manual Dagu graph using the retained Codex SDK/OmniRoute lane." + }, + "frozen_inputs": { + "base_revision": "44b0fa94357498b51afdbbb2958219cec7d14ce4", + "tasks": [ + "native-tests", + "compact-tests", + "metadata", + "missing-mcp", + "missing-skill", + "observer", + "doctor", + "graph-env", + "enhanced-graph", + "enhanced-judge", + "peer-cooperation" + ], + "roles": [ + "integrator", + "scheduler", + "sol-worker", + "astra-judge", + "claude-peer" + ], + "sources": [ + { + "path": "examples/omniroute-codex-sdk/worker.py", + "sha256": "d93e4bb0e54f436d15b6c06375126eba51289f8b1513e5ef52dfacaa8a65a074" + }, + { + "path": "examples/omniroute-codex-sdk/test_worker.py", + "sha256": "b31d70450151925ac506e9cd018740e9d3d4ca4529a70f3a9d4f8b845d7e8da8" + }, + { + "path": "examples/omniroute-codex-sdk/worker.py.lock", + "sha256": "15e5e7cfeec11ac86d8f081742c726c0d70326b480894a81e5cc76a7d9225c44" + }, + { + "path": "examples/omniroute-codex-sdk/runtime.config.template.toml", + "sha256": "3602da96a99c2cc4a6f211695dcf0b8f46cd408cd10290b8b54537e38f0258d6" + }, + { + "path": "examples/omniroute-codex-sdk/runtime-worker.yaml", + "sha256": "b3093a32ad708f09b81893f9d65975f9f01f99078976929e82830e6ec1b6a7b4" + }, + { + "path": "examples/omniroute-codex-sdk/agents/runtime-judge.toml", + "sha256": "0a0b549d3007c75ccb35be3a1d765de31d0504abdd35dfad1e3d68ad4daead55" + } + ], + "inputs": [ + { + "path": "examples/omniroute-codex-sdk/acceptance-plan.json", + "sha256": "5b046e6e30802bbe66d837030ae3c215d6fd401d524d48f51302269450d65d94" + }, + { + "path": "examples/omniroute-codex-sdk/rerun-plan.json", + "sha256": "3f4e9c441ca1b34c9a425cc3e8344e979b99757370506970fd7f760ac55d8730" + }, + { + "path": ".claude/skills/omniroute-runtime-worker/SKILL.md", + "sha256": "14593cbbbe7a89507c0559dd975dff4a2273a46f0e828a7689f79d650767d28f" + }, + { + "path": "blueprints/runtime-workers/skills/manifest.json", + "sha256": "3bc75e2e29e624de301227da157d427d81f1590526f837bb7a0c4b74f0b65439" + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime.config.template.toml.txt", + "sha256": "5c023dcf0c9c80a3aaf303dda47a268250c61b054551e3f8ccf213033609c72e" + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime-worker.yaml.txt", + "sha256": "82dd567b9e0fd8cc300b516fed535584472a499f63431ddeb030a36065c91426" + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/post-env-import-runtime-worker.yaml.txt", + "sha256": "46cab557d04fcb6bc5ad1be96c5b46d4dd82a8bfc25fe719fb095deb64a7e756" + } + ], + "evaluation": [ + { + "path": "examples/omniroute-codex-sdk/test_worker.py", + "sha256": "b31d70450151925ac506e9cd018740e9d3d4ca4529a70f3a9d4f8b845d7e8da8" + }, + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/repaired-judge-oracle-output.txt", + "sha256": "7b49b6e997017b1cde21f9aa33af3d5510926ad182f3211d0dd40cd71762a44a" + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/deadline300-judge-oracle-output.txt", + "sha256": "b9032a013f9d5b050a0940a2c8142d75ff75d6e560e88e77c58383d4c94fc679" + } + ] + }, + "predeclared_metrics": { + "quality_rule": "Original acceptance plan preceded provider trials; failed300-second attempt retained. Source-backed rerun plan preceded the new trial. Require actual skill body, Context Mode count, Serena symbol, one unmodified role spawn, exact unchanged oracle exit0, parent/native graph completion and closed SDK cleanup. This is bounded integration, not a comparative SDK winner trial.", + "usage_rule": "Latest cumulative native snapshot counted once for each parent and child; each observation carries only its own thread. Cached input/creation and inclusive output are disjoint categories; reasoning is an output subset. Failed parent counter is partial. Observer response sums independently corroborate the same counters and are never added. Provider retries, overall task usage and savings remain unknown." + }, + "runtime_and_platform": { + "platform": "Linux x86_64; owned native worker home/project and process-scoped OmniRoute Responses provider.", + "tools": [ + { + "name": "Codex Python SDK/native CLI", + "version": "0.159.2" + }, + { + "name": "Context Mode", + "version": "1.0.169" + }, + { + "name": "Serena", + "version": "2.0.0.dev0 selected pin" + }, + { + "name": "Dagu", + "version": "2.16.6" + }, + { + "name": "mitmproxy", + "version": "12.2.3" + }, + { + "name": "RTK", + "version": "0.50.0" + }, + { + "name": "native Claude follow-up", + "version": "2.1.285" + } + ], + "isolation": "Separate bounded writing worktrees, new private native home and state, read-only parent/child sandbox, at most three concurrent children, owned loopback metadata observer and no scheduler/global account changes." + }, + "commands": [ + "rtk uv run --locked --script examples/omniroute-codex-sdk/test_worker.py", + "rtk uv run --locked --script examples/omniroute-codex-sdk/test_worker.py NativeTransportTests.test_preflight_cli_emits_one_compact_result_or_explicit_catalog_details NativeTransportTests.test_preflight_discovers_native_mcp_skill_and_roles_without_inference NativeTransportTests.test_preflight_requirements_are_explicit_and_do_not_change_turns NativeTransportTests.test_preflight_missing_mcp_and_skill_fail_without_inference", + "rtk proxy uv run --locked --script examples/omniroute-codex-sdk/worker.py --workspace --codex-home --base-url --preflight --require-mcp context-mode --require-mcp serena --require-skill using-superpowers --timeout 60", + "Same native preflight with --require-mcp no-such-runtime-server", + "Same native preflight with --require-skill no-such-runtime-skill", + "rtk proxy env STACK_WORKER_OBSERVATION= uv tool run --from mitmproxy==12.2.3 mitmdump --quiet --mode reverse:http://127.0.0.1:20128 --listen-host 127.0.0.1 --listen-port --set confdir= --set flow_detail=0 --scripts tools/runtime-worker-evidence/gateway_observer.py", + "rtk proxy env CODEX_HOME= codex doctor --json", + "rtk proxy env STACK_ROOT= WORKER_PROJECT= WORKER_CODEX_HOME= WORKER_BASE_URL= WORKER_TASK_FILE= WORKER_RESULT= dagu start --context local --dagu-home --run-id examples/omniroute-codex-sdk/runtime-worker.yaml", + "Native runtime-judge executes rtk npm test exactly once in the unchanged owned upstream fixture", + "Native Claude Opus5.5/Max owned background follow-up with task-selected source/owner handoff; rtk proxy claude stop returned exit0 without a confirmed final handoff" + ], + "observations": [ + { + "id": "sdk-tests-before-start", + "task": "native-tests", + "role": "integrator", + "condition": "candidate", + "attempt": 1, + "command_index": 0, + "evidence_class": "native_cli_execution", + "scope": "Native app-server integration fixtures before explicit start", + "status": "failed", + "exit_code": 1, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "sdk-tests-before-metadata", + "task": "native-tests", + "role": "integrator", + "condition": "candidate", + "attempt": 2, + "command_index": 0, + "evidence_class": "native_cli_execution", + "scope": "Native app-server integration fixtures before metadata normalization", + "status": "failed", + "exit_code": 1, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "sdk-tests-full", + "task": "native-tests", + "role": "integrator", + "condition": "candidate", + "attempt": 3, + "command_index": 0, + "evidence_class": "native_cli_execution", + "scope": "12 locally authored native integration checks; unchanged upstream suite remains separate", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "sdk-tests-compact", + "task": "compact-tests", + "role": "integrator", + "condition": "candidate", + "attempt": 1, + "command_index": 1, + "evidence_class": "native_cli_execution", + "scope": "Four changed-contract native integration checks", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "metadata-ready", + "task": "metadata", + "role": "integrator", + "condition": "candidate", + "attempt": 1, + "command_index": 2, + "evidence_class": "native_cli_execution", + "scope": "Native MCP/skill/config discovery, no model turn", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "missing-mcp", + "task": "missing-mcp", + "role": "integrator", + "condition": "candidate", + "attempt": 1, + "command_index": 3, + "evidence_class": "native_cli_execution", + "scope": "Expected missing-server rejection before inference", + "status": "failed", + "exit_code": 2, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "missing-skill", + "task": "missing-skill", + "role": "integrator", + "condition": "candidate", + "attempt": 1, + "command_index": 4, + "evidence_class": "native_cli_execution", + "scope": "Expected missing-skill rejection before inference", + "status": "failed", + "exit_code": 2, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "observer-port-occupied", + "task": "observer", + "role": "integrator", + "condition": "candidate", + "attempt": 1, + "command_index": 5, + "evidence_class": "native_cli_execution", + "scope": "Owned metadata observer startup", + "status": "failed", + "exit_code": 1, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "observer-started", + "task": "observer", + "role": "integrator", + "condition": "candidate", + "attempt": 2, + "command_index": 5, + "evidence_class": "native_cli_execution", + "scope": "Owned metadata observer startup and final clean stop", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "config-doctor", + "task": "doctor", + "role": "integrator", + "condition": "candidate", + "attempt": 1, + "command_index": 6, + "evidence_class": "native_cli_execution", + "scope": "Config loaded; default native auth absent in new home without SDK process overrides", + "status": "failed", + "exit_code": 1, + "quality": { + "semantic": null, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "dagu-env-failure", + "task": "graph-env", + "role": "scheduler", + "condition": "candidate", + "attempt": 1, + "command_index": 7, + "evidence_class": "native_cli_execution", + "scope": "Task env import absent; readiness exit2, dependent worker aborted before inference", + "status": "failed", + "exit_code": 1, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + }, + { + "id": "graph-deadline300", + "task": "enhanced-graph", + "role": "sol-worker", + "condition": "candidate", + "attempt": 1, + "command_index": 7, + "evidence_class": "model_task_execution", + "scope": "Bounded Sol-Max SDK skill/MCP/native-judge workflow through OmniRoute", + "status": "failed", + "exit_code": 2, + "quality": { + "semantic": false, + "contract": false + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": 30883, + "cache_creation": 0, + "cache_read": 178816, + "output": 3365, + "reasoning_in_output": 1625, + "total": 213064, + "native_retries": null + } + }, + { + "id": "judge-deadline300", + "task": "enhanced-judge", + "role": "astra-judge", + "condition": "candidate", + "attempt": 1, + "command_index": 8, + "evidence_class": "model_task_execution", + "scope": "Astra child oracle completed inside the failed300-second parent attempt", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/deadline300-judge-oracle-output.txt", + "sha256": "b9032a013f9d5b050a0940a2c8142d75ff75d6e560e88e77c58383d4c94fc679" + } + ], + "usage": { + "uncached_input": 29305, + "cache_creation": 0, + "cache_read": 76160, + "output": 1908, + "reasoning_in_output": 1050, + "total": 107373, + "native_retries": null + } + }, + { + "id": "graph-repaired", + "task": "enhanced-graph", + "role": "sol-worker", + "condition": "candidate", + "attempt": 2, + "command_index": 7, + "evidence_class": "model_task_execution", + "scope": "Bounded Sol-Max SDK skill/MCP/native-judge workflow through OmniRoute", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": 19813, + "cache_creation": 0, + "cache_read": 131712, + "output": 2288, + "reasoning_in_output": 1122, + "total": 153813, + "native_retries": null + } + }, + { + "id": "judge-repaired", + "task": "enhanced-judge", + "role": "astra-judge", + "condition": "candidate", + "attempt": 2, + "command_index": 8, + "evidence_class": "model_task_execution", + "scope": "Bounded Sol-Max SDK skill/MCP/native-judge workflow through OmniRoute", + "status": "passed", + "exit_code": 0, + "quality": { + "semantic": true, + "contract": true + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/repaired-judge-oracle-output.txt", + "sha256": "7b49b6e997017b1cde21f9aa33af3d5510926ad182f3211d0dd40cd71762a44a" + } + ], + "usage": { + "uncached_input": 2604, + "cache_creation": 0, + "cache_read": 61952, + "output": 1488, + "reasoning_in_output": 878, + "total": 66044, + "native_retries": null + } + }, + { + "id": "claude-followup-unconfirmed", + "task": "peer-cooperation", + "role": "claude-peer", + "condition": "candidate", + "attempt": 1, + "command_index": 9, + "evidence_class": "model_task_execution", + "scope": "Owned native Claude follow-up stopped without confirmed final handoff", + "status": "failed", + "exit_code": 0, + "quality": { + "semantic": false, + "contract": null + }, + "artifacts": [ + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06" + } + ], + "usage": { + "uncached_input": null, + "cache_creation": null, + "cache_read": null, + "output": null, + "reasoning_in_output": null, + "total": null, + "native_retries": null + } + } + ], + "failures_and_skips": [ + { + "run_id": "sdk-tests-before-start", + "reason": "TransportClosedError; public low-level client must start before initialize." + }, + { + "run_id": "sdk-tests-before-metadata", + "reason": "After one bounded Sol repair, low-level initialize omitted serverInfo. Astra accepted primary-source userAgent normalization; exact version still validated." + }, + { + "run_id": "missing-mcp", + "reason": "Expected discriminating preflight exit2; no inference submitted and local cleanup closed." + }, + { + "run_id": "missing-skill", + "reason": "Expected discriminating preflight exit2; no inference submitted and local cleanup closed." + }, + { + "run_id": "observer-port-occupied", + "reason": "First25283 bind exit1. Started only a new owned observer25291; other listener preserved." + }, + { + "run_id": "config-doctor", + "reason": "Whole doctor exit1 because default native auth is absent in the new owned home; config.load passed. SDK process overrides were not part of doctor." + }, + { + "run_id": "dagu-env-failure", + "reason": "Native Dagu filters task binding exports; readiness exit2 and worker aborted. Actual env import repair and source cited in receipt." + }, + { + "run_id": "graph-deadline300", + "reason": "MCP calls and child oracle passed but parent aborted at300 seconds. Gateway-prefixed spawn default also caused one rejected call before explicit fallback. Native failed parent latest snapshot is partial, not complete provider coverage." + }, + { + "run_id": "claude-followup-unconfirmed", + "reason": "Native follow-up session stopped cleanly; no confirmed SendMessage/final packet, no peer approval or new contact count. Usage unknown." + } + ], + "limitations": [ + "One unchanged arithmetic fixture and bounded integration; no universal highest-quality model, framework or SDK ranking.", + "169 enabled skills were visible through native discovery. This run read using-superpowers and exercised three selected MCP calls; it does not qualify every installed skill, tool, language server, plugin or hook.", + "Native hook support and live web search are configured, but their execution is unmeasured here. No scheduler, schedule, hook or global account configuration was installed by this kit.", + "Native parent and child cumulative usage are separate scopes. Cached input and reasoning are subsets; observer response counters corroborate the same usage and must not be added. Failed/interrupted and complete provider usage, billing and token savings remain unknown.", + "Each observed completed stream also has an unclassified flow_error record. Native results completed; transport is not described as error-free, and requested model/provider labels are not backend identity attestation.", + "The separate Claude SDK Devin bridge retains its failed/unqualified status. Earlier native Claude-to-SDK acceptance is a historical separate callsite, not a rerun against this source.", + "The follow-up native Claude cooperation session was stopped after no confirmed SendMessage/final packet; no peer approval or new owner-contact count is claimed.", + "The isolated kit is a scoped private worker configuration. Live owners retain shared worker policy, host-wide catalogs/defaults and dashboard checkpoint ownership." + ], + "decision_and_scope": { + "decision": "adopt_within_scope", + "scope": "Bounded Sol-Max SDK skill/MCP/native-judge workflow through OmniRoute", + "qualification_run_ids": [ + "graph-repaired", + "judge-repaired" + ] + }, + "rollback": "Stop only the owned invocation/observer; retain failed and successful private native artifacts. Select the historical plain native SDK recipe if enhanced MCP/role readiness fails. No shared service/account rollback required.", + "next_decision_changing_test": "Qualify task-specific additional skills/MCP/languages, installed hooks and any schedule with their own native execution and lifecycle gates. Repair and qualify the separate Claude SDK bridge before promotion; preserve the existing frozen SDK comparison gate.", + "usage_assessment": { + "claim": "none", + "coverage": "partial", + "expected_run_ids": [ + "sdk-tests-before-start", + "sdk-tests-before-metadata", + "sdk-tests-full", + "sdk-tests-compact", + "metadata-ready", + "missing-mcp", + "missing-skill", + "observer-port-occupied", + "observer-started", + "config-doctor", + "dagu-env-failure", + "graph-deadline300", + "judge-deadline300", + "graph-repaired", + "judge-repaired", + "claude-followup-unconfirmed" + ], + "coverage_artifact": null + } +} diff --git a/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json b/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json index 2b16896b4..3fb54c1b2 100644 --- a/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json +++ b/blueprints/convergence-practice/omniroute-runtime-workers/experiment.json @@ -69,7 +69,7 @@ ], "sources": [ { - "path": "examples/omniroute-codex-sdk/worker.py", + "path": "evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-worker.py.txt", "sha256": "8dfa1799dc2ce034548eb2581befe61bef480728cc541a451e960bb48decc651" }, { @@ -83,7 +83,7 @@ "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" }, { - "path": ".claude/skills/omniroute-runtime-worker/SKILL.md", + "path": "evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-dispatcher.md", "sha256": "857a00f0c3f4088a20662f32f422b30c4697d0c267c0db1f9dbb95dfcbe39ce5" } ], @@ -93,7 +93,7 @@ "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e" }, { - "path": "examples/omniroute-codex-sdk/test_worker.py", + "path": "evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-test_worker.py.txt", "sha256": "ea30d5bd0568f1e179e6460647ef61f2ca1ca025bda574f5f35a315eeee2ae2a" }, { @@ -730,7 +730,8 @@ "Source/evaluation artifacts pin the final formatting-equivalent implementation; exact pre-format live worker bytes are retained in native commits named in the receipt.", "The 136-skill native installation and check are separate from per-task quality. Upstream source suites, authored local fixtures and actual provider execution remain separate.", "The new native Claude parent reports list-price cost and its own usage scope, separate from the external SDK child. The new child contributes 31,005 tokens once; distinct successful SDK threads now total 259,749. Parent usage is not added to that SDK total. Original independent transport reconciliation covers only the earlier 228,744 direct-trial tokens.", - "The first callsite record check rejected receipt kind native_model_e2e as an observation evidence_class. The published observation class was corrected to the validator-supported model_task_execution, matching retained provider trials; no run or receipt outcome changed. Independent review also corrected allowed Bash/Read/Skill versus actually invoked Read/Bash." + "The first callsite record check rejected receipt kind native_model_e2e as an observation evidence_class. The published observation class was corrected to the validator-supported model_task_execution, matching retained provider trials; no run or receipt outcome changed. Independent review also corrected allowed Bash/Read/Skill versus actually invoked Read/Bash.", + "Pre-enhancement source, test and dispatcher bytes from public commit ef90678c199a53bb43344fedec2fbcd5b6bf5c58 are archived under evidence/artifacts/omniroute-runtime-workers-20260930. Frozen-input paths now point to those unchanged bytes, preserving historical hashes after the separately recorded enhancement work." ], "decision_and_scope": { "decision": "adopt_within_scope", diff --git a/evidence/artifacts/omniroute-runtime-enhancements-20260930/deadline300-judge-oracle-output.txt b/evidence/artifacts/omniroute-runtime-enhancements-20260930/deadline300-judge-oracle-output.txt new file mode 100644 index 000000000..b79a7c2be --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-enhancements-20260930/deadline300-judge-oracle-output.txt @@ -0,0 +1,11 @@ +> test +> node --test math.test.js +✔ math.test.js (71.889129ms) +ℹ tests 1 +ℹ suites 0 +ℹ pass 1 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 84.912717 diff --git a/evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime-worker.yaml.txt b/evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime-worker.yaml.txt new file mode 100644 index 000000000..7cdb9b606 --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime-worker.yaml.txt @@ -0,0 +1,22 @@ +# Dagu 2.16.6 / 58fed633d58c1dd1319091fdb2c2f6158ecfa053. +# Native graph/run/depends/timeout format from examples/embedded/local/workflow.yaml +# and the existing blueprints/convergence-practice/job-recovery/run.py recipe. +# Export only the task-specific path bindings described in enhancements.md. +type: graph +timeout_sec: 420 +max_active_runs: 1 +steps: + - id: readiness + run: >- + rtk uv run --locked --script "${STACK_ROOT}/examples/omniroute-codex-sdk/worker.py" + --workspace "${WORKER_PROJECT}" --codex-home "${WORKER_CODEX_HOME}" + --base-url "${WORKER_BASE_URL}" + --preflight --require-mcp context-mode --require-skill using-superpowers --timeout 60 + - id: worker + depends: [readiness] + run: >- + rtk uv run --locked --script "${STACK_ROOT}/examples/omniroute-codex-sdk/worker.py" + --workspace "${WORKER_PROJECT}" --codex-home "${WORKER_CODEX_HOME}" + --base-url "${WORKER_BASE_URL}" + --sandbox read-only --timeout 300 --prompt - + --native-result "${WORKER_RESULT}" < "${WORKER_TASK_FILE}" diff --git a/evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime.config.template.toml.txt b/evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime.config.template.toml.txt new file mode 100644 index 000000000..0d607b0b2 --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime.config.template.toml.txt @@ -0,0 +1,51 @@ +# Native Codex configuration for a NEW private SDK worker home, not a named profile. +# Source: openai/codex ff6aec96948b70d94983af2641a6b67c94faeff5 +# codex-rs/config/src/config_toml.rs (agents, MCP and hooks); +# codex-rs/cli/src/main.rs:1263 (app-server does not apply --profile). +# Render with tools/adoption/render_config.py as described in enhancements.md. +# The worker supplies its process-scoped provider/model/Max overrides. +model_reasoning_effort = "max" +web_search = "live" + +[agents] +enabled = true +max_concurrent_threads_per_session = 3 +default_subagent_model = "cx/gpt-6.1-sol-max" +default_subagent_reasoning_effort = "max" + +[agents.runtime-judge] +description = "Inspect a consequential runtime claim from original source and returned evidence; report a verdict without editing." +config_file = "agents/runtime-judge.toml" + +# Maintained context-mode 1.0.169 native stdio entry, adapted from +# adoption/templates/codex.config.template.toml. MCP readiness is required. +[mcp_servers.context-mode] +command = "${ECO_ROOT}/bin/node" +args = ["${ECO_ROOT}/tools/context-mode-1.0.169/lib/node_modules/context-mode/start.mjs"] +startup_timeout_sec = 60 +tool_timeout_sec = 120 +required = true +default_tools_approval_mode = "approve" +disabled_tools = ["ctx_upgrade", "ctx_purge"] + +[mcp_servers.context-mode.env] +RTK_TELEMETRY_DISABLED = "1" +CONTEXT_MODE_PLATFORM = "codex" + +# Native, task-selected code navigation. Require serena explicitly in readiness +# when the task needs it; discovery alone does not qualify a code-navigation run. +# Source: the maintained Codex/Serena native entry in the adoption template. +[mcp_servers.serena] +command = "${ECO_ROOT}/bin/serena" +args = ["start-mcp-server", "--transport", "stdio", "--project-from-cwd", "--context", "codex", "--enable-web-dashboard", "false", "--open-web-dashboard", "false", "--enable-gui-log-window", "false"] +startup_timeout_sec = 60 +tool_timeout_sec = 120 +enabled_tools = ["initial_instructions", "find_symbol", "find_referencing_symbols", "get_symbols_overview", "search_for_pattern"] + +[mcp_servers.serena.env] +SERENA_HOME = "${WORKER_STATE}/serena" + +[features] +hooks = true +daemon_auto_start = false +shell_snapshot = false diff --git a/evidence/artifacts/omniroute-runtime-enhancements-20260930/post-env-import-runtime-worker.yaml.txt b/evidence/artifacts/omniroute-runtime-enhancements-20260930/post-env-import-runtime-worker.yaml.txt new file mode 100644 index 000000000..6a9b681d7 --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-enhancements-20260930/post-env-import-runtime-worker.yaml.txt @@ -0,0 +1,29 @@ +# Dagu 2.16.6 / 58fed633d58c1dd1319091fdb2c2f6158ecfa053. +# Native graph/run/depends/timeout format from examples/embedded/local/workflow.yaml +# and the existing blueprints/convergence-practice/job-recovery/run.py recipe. +# Export only the task-specific path bindings described in enhancements.md. +type: graph +timeout_sec: 420 +max_active_runs: 1 +env: + - STACK_ROOT: ${STACK_ROOT} + - WORKER_PROJECT: ${WORKER_PROJECT} + - WORKER_CODEX_HOME: ${WORKER_CODEX_HOME} + - WORKER_BASE_URL: ${WORKER_BASE_URL} + - WORKER_RESULT: ${WORKER_RESULT} + - WORKER_TASK_FILE: ${WORKER_TASK_FILE} +steps: + - id: readiness + run: >- + rtk uv run --locked --script "${STACK_ROOT}/examples/omniroute-codex-sdk/worker.py" + --workspace "${WORKER_PROJECT}" --codex-home "${WORKER_CODEX_HOME}" + --base-url "${WORKER_BASE_URL}" + --preflight --require-mcp context-mode --require-skill using-superpowers --timeout 60 + - id: worker + depends: [readiness] + run: >- + rtk uv run --locked --script "${STACK_ROOT}/examples/omniroute-codex-sdk/worker.py" + --workspace "${WORKER_PROJECT}" --codex-home "${WORKER_CODEX_HOME}" + --base-url "${WORKER_BASE_URL}" + --sandbox read-only --timeout 300 --prompt - + --native-result "${WORKER_RESULT}" < "${WORKER_TASK_FILE}" diff --git a/evidence/artifacts/omniroute-runtime-enhancements-20260930/repaired-judge-oracle-output.txt b/evidence/artifacts/omniroute-runtime-enhancements-20260930/repaired-judge-oracle-output.txt new file mode 100644 index 000000000..779b83847 --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-enhancements-20260930/repaired-judge-oracle-output.txt @@ -0,0 +1,11 @@ +> test +> node --test math.test.js +✔ math.test.js (51.423202ms) +ℹ tests 1 +ℹ suites 0 +ℹ pass 1 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms 59.054462 diff --git a/evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-dispatcher.md b/evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-dispatcher.md new file mode 100644 index 000000000..bcd21d94d --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-dispatcher.md @@ -0,0 +1,42 @@ +--- +name: omniroute-runtime-worker +description: Delegate a bounded foundation engineering task from Claude to the native Codex SDK worker through the selected OmniRoute gateway. +--- + +Read `examples/omniroute-codex-sdk/README.md` for invocation and lifecycle details. +Use this project's `examples/omniroute-codex-sdk/worker.py` through Claude's native +Bash tool. The primary route is `cx/gpt-6.1-sol-max`, with native Max effort. +The coordinator retains its native Claude account and model route. + +Give a writing worker its own worktree, bounded file ownership, an executable +acceptance condition and an existing private Codex home. Tell it other workers +are present and that it must preserve their edits. Feed the task on stdin: + +```sh +rtk uv run --locked --script examples/omniroute-codex-sdk/worker.py \ + --workspace "$WORKER_PROJECT" \ + --codex-home "$PRIVATE_WORKER_HOME" \ + --timeout 300 \ + --prompt - +``` + +Use the selected gateway's native Responses lane at loopback port 20128. Keep +native caches, tools and project skill discovery intact; load only task-relevant +skill bodies. Install selected skills through the existing runtime-worker skill +recipe, rather than importing the entire catalog into the task prompt. Optional +MCP services require their own configuration and acceptance. + +Keep returned thread IDs private and use `--resume` for continuation. The latest +thread usage snapshot includes previous turns; count it once. A deadline invokes +native interruption and child cleanup; remote termination and unknown provider +usage remain unverified. Do not automatically replay a failed writing task. + +Use explicit `--model cx/gpt-6-astra-max` for consequential architecture, +conflicting primary evidence, or a failure unresolved after one bounded Sol +repair. Record that trigger and the acceptance result. The separate Claude SDK +bridge remains a trial after its gateway errors; it is not the primary worker. + +Sources: [Claude native project skills](https://code.claude.com/docs/en/skills) +and [official Codex SDK, rust-v0.159.2](https://github.com/openai/codex/tree/ff6aec96948b70d94983af2641a6b67c94faeff5/sdk/python). +Functional scope and retained failures are recorded in +`docs/decisions/2026-09-30-omniroute-runtime-workers.md`. diff --git a/evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-test_worker.py.txt b/evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-test_worker.py.txt new file mode 100644 index 000000000..13a658b1c --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-test_worker.py.txt @@ -0,0 +1,285 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.13,<3.14" +# dependencies = [ +# "openai-codex==0.159.2", +# ] +# /// +"""Local integration fixtures, not upstream tests or provider/model acceptance. + +The SSE fixture derives from openai/codex rust-v0.159.2 +codex-rs/core/tests/common/responses.rs::{sse,ev_response_created, +ev_assistant_message,ev_completed}. The SDK and bundled native runtime are real; +the loopback provider returns authored deterministic fixture responses. +""" + +import asyncio +import json +import os +import tempfile +import threading +import unittest +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from pathlib import Path + +import worker +from openai_codex import AsyncCodex + + +class FixtureGateway: + def __init__(self, mode="complete"): + self.mode = mode + self.requests = [] + self.release = threading.Event() + owner = self + + class Handler(BaseHTTPRequestHandler): + def log_message(self, *args): + pass + + def do_POST(self): + body = json.loads(self.rfile.read(int(self.headers["Content-Length"]))) + index = len(owner.requests) + owner.requests.append( + { + "path": self.path, + "body": body, + "request_id": self.headers.get("x-request-id"), + "has_authorization": "authorization" in self.headers, + } + ) + response_id = f"fixture_response_{index}" + events = [ + {"type": "response.created", "response": {"id": response_id}}, + { + "type": "response.output_item.done", + "item": { + "type": "message", + "role": "assistant", + "id": f"fixture_message_{index}", + "content": [{"type": "output_text", "text": f"fixture answer {index}"}], + }, + }, + ] + if owner.mode == "complete": + input_tokens, cached_tokens, output_tokens, reasoning_tokens = ( + (20, 5, 4, 2) if index == 0 else (30, 10, 6, 4) + ) + events.append( + { + "type": "response.completed", + "response": { + "id": response_id, + "usage": { + "input_tokens": input_tokens, + "input_tokens_details": {"cached_tokens": cached_tokens}, + "output_tokens": output_tokens, + "output_tokens_details": {"reasoning_tokens": reasoning_tokens}, + "total_tokens": input_tokens + output_tokens, + }, + }, + } + ) + encoded = "".join( + f"event: {event['type']}\ndata: {json.dumps(event)}\n\n" for event in events + ).encode() + self.send_response(200) + self.send_header("Content-Type", "text/event-stream") + self.send_header("Content-Length", str(len(encoded))) + self.end_headers() + if owner.mode == "stall": + owner.release.wait(10) + try: + self.wfile.write(encoded) + except (BrokenPipeError, ConnectionResetError): + pass + + self.server = ThreadingHTTPServer(("127.0.0.1", 0), Handler) + self.server.daemon_threads = True + self.thread = threading.Thread(target=self.server.serve_forever, daemon=True) + self.url = f"http://127.0.0.1:{self.server.server_port}/v1" + + def __enter__(self): + self.thread.start() + return self + + def __exit__(self, *args): + self.release.set() + self.server.shutdown() + self.server.server_close() + self.thread.join(2) + + +class NativeTransportTests(unittest.TestCase): + def setUp(self): + self.temp = tempfile.TemporaryDirectory() + self.addCleanup(self.temp.cleanup) + self.project = Path(self.temp.name) / "project" + self.home = Path(self.temp.name) / "codex-home" + self.project.mkdir() + self.home.mkdir(mode=0o700) + + def args(self, gateway, *extra): + return worker.parse_args( + [ + "--workspace", + str(self.project), + "--codex-home", + str(self.home), + "--base-url", + gateway.url, + "--request-id", + "fixture-owned-request", + "--sandbox", + "read-only", + "--timeout", + "15", + "--no-provider-retries", + *extra, + ] + ) + + def run_worker(self, args, *, sdk_factory=AsyncCodex): + events = [] + instances, owned_pids = [], [] + + def create_sdk(config): + instance = sdk_factory(config=config) + instances.append(instance) + return instance + + def observe(event): + events.append(event) + # Observation only: inspect the PID of this test's own SDK child. + # Native source: sdk/python/src/openai_codex/client.py::_start_process. + process = instances[-1]._client._sync._proc + if process is not None: + owned_pids.append(process.pid) + + result = asyncio.run( + worker.run_worker( + args, "One bounded fixture task.", sdk_factory=create_sdk, on_event=observe + ) + ) + for pid in owned_pids: + with self.assertRaises(ProcessLookupError): + os.kill(pid, 0) + return result, events + + def assert_accepted(self, result): + self.assertEqual(result["status"], "completed", result) + self.assertEqual(result["cleanup_status"], "closed", result) + self.assertEqual(result["usage_status"], "reported", result) + self.assertEqual(result["usage_scope"], "native_thread_cumulative", result) + + def test_native_payload_header_tools_and_nonadditive_resume(self): + with FixtureGateway() as gateway: + first, events = self.run_worker(self.args(gateway)) + self.assert_accepted(first) + self.assertEqual(first["final_response"], "fixture answer 0") + self.assertEqual(events[0]["event"], "thread_ready") + second, _ = self.run_worker(self.args(gateway, "--resume", first["thread_id"])) + self.assert_accepted(second) + self.assertEqual(second["thread_id"], first["thread_id"]) + self.assertEqual(second["thread_mode"], "resumed") + self.assertEqual(len(gateway.requests), 2) + for request in gateway.requests: + self.assertEqual(request["path"], "/v1/responses") + self.assertEqual(request["request_id"], "fixture-owned-request") + self.assertFalse(request["has_authorization"]) + self.assertEqual(request["body"]["model"], worker.DEFAULT_MODEL) + self.assertEqual(request["body"]["reasoning"]["effort"], "max") + # Native Sol/Astra ResponsesLite carries tools inside input. + # Source: core/src/client.rs:902–933 at rust-v0.159.2. + tool_prefix = request["body"]["input"][0] + self.assertEqual(tool_prefix["type"], "additional_tools") + self.assertTrue(tool_prefix["tools"]) + self.assertIn("functions", [tool.get("name") for tool in tool_prefix["tools"]]) + self.assertEqual( + gateway.requests[0]["body"]["prompt_cache_key"], + gateway.requests[1]["body"]["prompt_cache_key"], + ) + self.assertEqual( + gateway.requests[0]["body"]["input"][0]["id"], + gateway.requests[1]["body"]["input"][0]["id"], + ) + self.assertIn("fixture answer 0", json.dumps(gateway.requests[1]["body"]["input"])) + first_total, second_total = first["usage"]["total"], second["usage"]["total"] + self.assertEqual(first_total["inputTokens"], 20) + self.assertEqual(first_total["outputTokens"], 4) + self.assertEqual(first_total["cachedInputTokens"], 5) + self.assertEqual(first_total["reasoningOutputTokens"], 2) + self.assertEqual(second_total["inputTokens"], 50) + self.assertEqual(second_total["outputTokens"], 10) + self.assertEqual(second_total["cachedInputTokens"], 15) + self.assertEqual(second_total["reasoningOutputTokens"], 6) + # Cached/reasoning counters are subsets; never add them to total. + self.assertEqual(second_total["totalTokens"], 60) + self.assertEqual(second["usage"]["last"]["totalTokens"], 36) + + def test_explicit_astra_model_is_preserved(self): + with FixtureGateway() as gateway: + selected = "cx/gpt-6-astra-max" + result, _ = self.run_worker(self.args(gateway, "--model", selected)) + self.assert_accepted(result) + self.assertEqual(gateway.requests[0]["body"]["model"], selected) + self.assertEqual(gateway.requests[0]["body"]["reasoning"]["effort"], "max") + + def test_incomplete_stream_negative_control_fails_acceptance(self): + with FixtureGateway("incomplete") as gateway: + result, _ = self.run_worker(self.args(gateway)) + with self.assertRaises(AssertionError): + self.assert_accepted(result) + self.assertEqual(result["status"], "failed", result) + self.assertEqual(result["usage_status"], "unknown") + self.assertIsNone(result["usage"]) + self.assertEqual(len(gateway.requests), 1) + self.assertEqual(result["cleanup_status"], "closed") + + def test_wrong_wire_api_negative_control_never_submits(self): + def wrong_provider(config): + config.config_overrides = tuple( + value.replace('wire_api="responses"', 'wire_api="chat"') + for value in config.config_overrides + ) + return AsyncCodex(config=config) + + with FixtureGateway() as gateway: + result, _ = self.run_worker(self.args(gateway), sdk_factory=wrong_provider) + with self.assertRaises(AssertionError): + self.assert_accepted(result) + self.assertEqual(result["status"], "failed", result) + self.assertEqual(result["phase"], "initialize") + self.assertFalse(result["model_inference_submitted"]) + self.assertIsNone(result["usage"]) + self.assertFalse(gateway.requests) + self.assertEqual(result["cleanup_status"], "closed") + + def test_deadline_interrupts_native_turn_and_closes(self): + with FixtureGateway("stall") as gateway: + result, _ = self.run_worker(self.args(gateway, "--timeout", "2")) + self.assertEqual(result["status"], "deadline_exceeded", result) + self.assertEqual(result["interrupt_status"], "requested", result) + self.assertEqual(result["cleanup_status"], "closed") + self.assertEqual(result["usage_status"], "unknown") + self.assertIsNone(result["usage"]) + + def test_native_artifact_is_private_and_never_overwritten(self): + destination = Path(self.temp.name) / "native-result.json" + with FixtureGateway() as gateway: + args = self.args(gateway, "--native-result", str(destination)) + result, _ = self.run_worker(args) + self.assert_accepted(result) + retained = destination.read_bytes() + native = json.loads(retained) + self.assertTrue(native["items"]) + self.assertEqual(destination.stat().st_mode & 0o777, 0o600) + duplicate, _ = self.run_worker(args) + self.assertEqual(duplicate["status"], "failed", duplicate) + self.assertEqual(duplicate["phase"], "retain_native_result") + self.assertEqual(duplicate["error_type"], "FileExistsError") + self.assertEqual(destination.read_bytes(), retained) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-worker.py.txt b/evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-worker.py.txt new file mode 100644 index 000000000..bb493b8bf --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-worker.py.txt @@ -0,0 +1,292 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.13,<3.14" +# dependencies = [ +# "openai-codex==0.159.2", +# ] +# /// +"""One native Codex SDK turn through an invocation-scoped OmniRoute provider. + +Derived from openai/codex rust-v0.159.2, commit +ff6aec96948b70d94983af2641a6b67c94faeff5, sdk/python/examples/{01,05,14}_* +and sdk/python/src/openai_codex/{api,client,_run}.py. See README.md for sources. +""" + +from __future__ import annotations + +import argparse +import asyncio +import json +import os +import re +import sys +import uuid +from collections import Counter +from pathlib import Path +from urllib.parse import urlsplit + +from openai_codex import ApprovalMode, AsyncCodex, CodexConfig, Sandbox +from openai_codex.types import ReasoningEffort + +SDK_VERSION = "0.159.2" +PROVIDER = "omniroute_runtime" +DEFAULT_MODEL = "cx/gpt-6.1-sol-max" +DEFAULT_BASE_URL = "http://127.0.0.1:20128/v1" +CLEANUP_TIMEOUT = 5.0 + + +def gateway_url(value: str) -> str: + """Keep the owned gateway and any explicit observer on HTTP loopback /v1.""" + parsed = urlsplit(value) + if ( + parsed.scheme != "http" + or parsed.hostname not in {"127.0.0.1", "localhost", "::1"} + or parsed.port is None + or parsed.username is not None + or parsed.password is not None + or parsed.query + or parsed.fragment + or parsed.path.rstrip("/") != "/v1" + ): + raise argparse.ArgumentTypeError("expected a port-qualified HTTP loopback /v1 URL") + return value.rstrip("/") + + +def request_id(value: str) -> str: + if not re.fullmatch(r"[A-Za-z0-9_.:-]{1,96}", value): + raise argparse.ArgumentTypeError("request id must be 1–96 ASCII identifier characters") + return value + + +def positive_seconds(value: str) -> float: + seconds = float(value) + if not 0 < seconds <= 3600: + raise argparse.ArgumentTypeError( + "timeout must be greater than zero and at most 3600 seconds" + ) + return seconds + + +def runtime_config(args: argparse.Namespace) -> CodexConfig: + """Only the SDK child receives these supported native CLI overrides.""" + prefix = f"model_providers.{PROVIDER}." + quoted = lambda value: json.dumps(value, ensure_ascii=False) # noqa: E731 + overrides = ( + "model_provider=" + quoted(PROVIDER), + "model=" + quoted(args.model), + 'model_reasoning_effort="max"', + prefix + 'name="OmniRoute runtime workers"', + prefix + "base_url=" + quoted(args.base_url), + prefix + 'wire_api="responses"', + prefix + "requires_openai_auth=false", + prefix + "supports_websockets=false", + prefix + 'http_headers={"x-request-id"=' + quoted(args.request_id) + "}", + ) + if args.api_key_env: + if not re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", args.api_key_env): + raise ValueError("api-key-env must name an environment variable") + overrides += (prefix + "env_key=" + quoted(args.api_key_env),) + # Native retry settings remain native. The caller may disarm them for a + # measured acceptance attempt; there is no wrapper retry or agent loop. + if args.no_provider_retries: + overrides += (prefix + "request_max_retries=0", prefix + "stream_max_retries=0") + env = {"CONTEXT_MODE_PROJECT_DIR": str(args.workspace.resolve())} + if args.codex_home: + env["CODEX_HOME"] = str(args.codex_home.resolve()) + return CodexConfig( + codex_bin=str(args.codex_bin.resolve()) if args.codex_bin else None, + config_overrides=overrides, + cwd=str(args.workspace.resolve()), + env=env, + client_name="omniroute_codex_runtime_worker", + client_title="OmniRoute Codex runtime worker", + ) + + +def result_record(result) -> dict: + """Retain native snapshots; total is cumulative and last is not a turn sum.""" + kinds = Counter( + item.model_dump(mode="json", by_alias=True).get("type") for item in result.items + ) + return { + "status": result.status.value, + "turn_id": result.id, + "final_response": result.final_response, + "duration_ms": result.duration_ms, + "item_counts": dict(kinds), + "usage_status": "reported" if result.usage is not None else "unknown", + "usage_scope": "native_thread_cumulative" if result.usage is not None else None, + "usage": result.usage.model_dump(mode="json", by_alias=True) + if result.usage is not None + else None, + } + + +def emit(value: dict) -> None: + print(json.dumps(value, ensure_ascii=False, separators=(",", ":")), flush=True) + + +async def run_worker( + args: argparse.Namespace, prompt: str, *, sdk_factory=AsyncCodex, on_event=emit +) -> dict: + """Use native start/resume/turn/interrupt/close, with one overall deadline.""" + codex = sdk_factory(config=runtime_config(args)) + turn = None + phase = "initialize" + record = { + "request_id": args.request_id, + "requested_model": args.model, + "requested_effort": "max", + "provider": PROVIDER, + "model_inference_submitted": False, + "usage_status": "unknown", + "usage_scope": None, + "usage": None, + } + try: + async with asyncio.timeout(args.timeout): + await codex.__aenter__() + server = codex.metadata.serverInfo + if server is None or server.version.split()[0] != SDK_VERSION: + raise RuntimeError("native runtime does not match the qualified SDK pin") + record["native_runtime"] = {"name": server.name, "version": server.version} + options = { + "cwd": str(args.workspace.resolve()), + "model": args.model, + "model_provider": PROVIDER, + "sandbox": Sandbox(args.sandbox), + "approval_mode": ApprovalMode(args.approval_mode), + } + phase = "thread_resume" if args.resume else "thread_start" + if args.resume: + thread = await codex.thread_resume(args.resume, **options) + else: + thread = await codex.thread_start(ephemeral=False, **options) + record["thread_id"] = thread.id + record["thread_mode"] = "resumed" if args.resume else "started" + selected = (await thread.read()).thread + if selected.model != args.model or selected.model_provider != PROVIDER: + raise RuntimeError("native thread did not retain the requested model and provider") + on_event({"event": "thread_ready", **record}) + phase = "turn_start" + # Codex owns tools, MCP discovery, skills, caching and compaction. + # There is no extra skill carrier or Responses prompt rewrite here. + record["model_inference_submitted"] = True + turn = await thread.turn(prompt, model=args.model, effort=ReasoningEffort.max) + phase = "turn_run" + result = await turn.run() + record.update(result_record(result)) + if args.native_result: + phase = "retain_native_result" + native = { + **record, + "items": [item.model_dump(mode="json", by_alias=True) for item in result.items], + } + fd = os.open(args.native_result, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600) + with os.fdopen(fd, "w", encoding="utf-8") as output: + json.dump(native, output, ensure_ascii=False, indent=2) + output.write("\n") + except (TimeoutError, asyncio.CancelledError) as exc: + record.update( + status="deadline_exceeded" if isinstance(exc, TimeoutError) else "cancelled", + phase=phase, + ) + if turn is not None: + try: + await asyncio.wait_for(turn.interrupt(), CLEANUP_TIMEOUT) + record["interrupt_status"] = "requested" + except Exception as interrupt_error: + record["interrupt_status"] = type(interrupt_error).__name__ + if isinstance(exc, asyncio.CancelledError): + raise + except Exception as exc: + # Error messages may carry private tool/provider content. Leave them in + # native private state; the public-facing result retains type and phase. + record.update(status="failed", error_type=type(exc).__name__, phase=phase) + finally: + try: + await asyncio.wait_for(codex.close(), CLEANUP_TIMEOUT) + record["cleanup_status"] = "closed" + except Exception as exc: + record.update(status="cleanup_failed", cleanup_status=type(exc).__name__) + return record + + +def parse_args(argv=None) -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--workspace", type=Path, default=Path.cwd()) + parser.add_argument("--prompt", default="-", help="one bounded task, or - to read stdin") + parser.add_argument("--resume", help="native thread id from an earlier invocation") + parser.add_argument( + "--model", + default=DEFAULT_MODEL, + help="explicit native/gateway model id; default Sol/max route", + ) + parser.add_argument("--base-url", type=gateway_url, default=DEFAULT_BASE_URL) + parser.add_argument("--request-id", type=request_id, default=uuid.uuid4().hex) + parser.add_argument("--timeout", type=positive_seconds, default=300.0) + parser.add_argument( + "--sandbox", + choices=[Sandbox.read_only.value, Sandbox.workspace_write.value], + default=Sandbox.workspace_write.value, + ) + parser.add_argument( + "--approval-mode", + choices=[mode.value for mode in ApprovalMode], + default=ApprovalMode.deny_all.value, + ) + parser.add_argument( + "--codex-bin", + type=Path, + help="explicit native 0.159.2 binary; defaults to the pinned SDK bundle", + ) + parser.add_argument( + "--codex-home", + type=Path, + help="optional private worker config/state; inherited when omitted", + ) + parser.add_argument( + "--api-key-env", + help="optional gateway credential variable name; no credential value is accepted", + ) + parser.add_argument( + "--no-provider-retries", + action="store_true", + help="disarm native request/stream retries for a measured attempt", + ) + parser.add_argument( + "--native-result", type=Path, help="retain full native items in a new private 0600 file" + ) + args = parser.parse_args(argv) + if not args.workspace.is_dir(): + parser.error("workspace must be an existing directory") + if args.codex_home and not args.codex_home.is_dir(): + parser.error("codex-home must be an existing private state directory") + if not args.model.strip(): + parser.error("model must be nonempty") + return args + + +def main() -> int: + args = parse_args() + prompt = sys.stdin.read() if args.prompt == "-" else args.prompt + if not prompt.strip(): + raise SystemExit("prompt must contain a bounded task") + try: + result = asyncio.run(run_worker(args, prompt)) + except KeyboardInterrupt: + emit( + { + "event": "cancelled", + "request_id": args.request_id, + "usage_status": "unknown", + "usage": None, + } + ) + return 130 + emit({"event": "result", **result}) + return 0 if result["status"] == "completed" else 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/evidence/receipts/omniroute-runtime-enhancements-20260930.json b/evidence/receipts/omniroute-runtime-enhancements-20260930.json new file mode 100644 index 000000000..66a49d48b --- /dev/null +++ b/evidence/receipts/omniroute-runtime-enhancements-20260930.json @@ -0,0 +1,731 @@ +{ + "schema_version": 1, + "id": "omniroute-runtime-enhancements-20260930", + "kind": "native_model_e2e", + "component_ids": [ + "codex", + "omniroute", + "context-mode", + "serena", + "dagu" + ], + "claim": "A scoped native Codex SDK Sol-Max worker completed skill use, selected Context Mode/Serena MCP calls, one Astra-Max native judge and an unchanged oracle through OmniRoute in a successful bounded Dagu graph.", + "limitations": [ + "One unchanged arithmetic fixture and bounded integration; no universal highest-quality model, framework or SDK ranking.", + "169 enabled skills were visible through native discovery. This run read using-superpowers and exercised three selected MCP calls; it does not qualify every installed skill, tool, language server, plugin or hook.", + "Native hook support and live web search are configured, but their execution is unmeasured here. No scheduler, schedule, hook or global account configuration was installed by this kit.", + "Native parent and child cumulative usage are separate scopes. Cached input and reasoning are subsets; observer response counters corroborate the same usage and must not be added. Failed/interrupted and complete provider usage, billing and token savings remain unknown.", + "Each observed completed stream also has an unclassified flow_error record. Native results completed; transport is not described as error-free, and requested model/provider labels are not backend identity attestation.", + "The separate Claude SDK Devin bridge retains its failed/unqualified status. Earlier native Claude-to-SDK acceptance is a historical separate callsite, not a rerun against this source.", + "The follow-up native Claude cooperation session was stopped after no confirmed SendMessage/final packet; no peer approval or new owner-contact count is claimed.", + "The isolated kit is a scoped private worker configuration. Live owners retain shared worker policy, host-wide catalogs/defaults and dashboard checkpoint ownership." + ], + "recorded_at": "2026-09-30T19:33:03Z", + "sources": { + "codex": { + "repository": "https://github.com/openai/codex", + "revision": "ff6aec96948b70d94983af2641a6b67c94faeff5", + "sdk_and_native_cli": "0.159.2", + "typed_preflight": "sdk/python/src/openai_codex/{async_client,generated/v2_all}.py", + "native_spawn": "codex-rs/core/src/agent/child_config.rs:50-84,196-235; role.rs:177-191" + }, + "context_mode": { + "repository": "https://github.com/mksglu/context-mode", + "revision": "589d8214d56740a28b5f7bf63167743d586b0b40", + "version": "1.0.169" + }, + "serena": { + "repository": "https://github.com/oraios/serena", + "revision": "c6fbd1c5932df2494ffa0020af5a9fbe80b82143" + }, + "dagu": { + "repository": "https://github.com/dagucloud/dagu", + "revision": "58fed633d58c1dd1319091fdb2c2f6158ecfa053", + "version": "2.16.6", + "root_env": "internal/spec/dag.go:694-710; internal/spec/variables.go:98-155" + }, + "observer": { + "repository": "https://github.com/mitmproxy/mitmproxy", + "revision": "6c09d56e4c29a92f5ad01b03199977584b8ea14f", + "version": "12.2.3", + "integration": "tools/runtime-worker-evidence/gateway_observer.py" + }, + "fixture": { + "repository": "https://github.com/diegosouzapw/OmniRoute", + "revision": "c1e30b7676975feb298b49eff6ff58923c04b89e", + "path": "tests/fixtures/devin-bridge/e2e-workspace", + "baseline": "evidence/receipts/omniroute-runtime-workers-20260930.json post-fix" + }, + "native_claude_workflows": "examples/claude-native/workflows/README.md; vendored agent-lab scripts retain their reviewed pins", + "rtk": "https://github.com/rtk-ai/rtk/blob/v0.50.0/hooks/rtk-awareness-full.md", + "skills": "blueprints/runtime-workers/skills/manifest.json and supported tools/adoption/install_skills.py; task bodies on demand" + }, + "source_hashes": { + "examples/omniroute-codex-sdk/worker.py": "d93e4bb0e54f436d15b6c06375126eba51289f8b1513e5ef52dfacaa8a65a074", + "examples/omniroute-codex-sdk/test_worker.py": "b31d70450151925ac506e9cd018740e9d3d4ca4529a70f3a9d4f8b845d7e8da8", + "examples/omniroute-codex-sdk/worker.py.lock": "15e5e7cfeec11ac86d8f081742c726c0d70326b480894a81e5cc76a7d9225c44", + "examples/omniroute-codex-sdk/runtime.config.template.toml": "3602da96a99c2cc4a6f211695dcf0b8f46cd408cd10290b8b54537e38f0258d6", + "examples/omniroute-codex-sdk/runtime-worker.yaml": "b3093a32ad708f09b81893f9d65975f9f01f99078976929e82830e6ec1b6a7b4", + "examples/omniroute-codex-sdk/agents/runtime-judge.toml": "0a0b549d3007c75ccb35be3a1d765de31d0504abdd35dfad1e3d68ad4daead55", + "examples/omniroute-codex-sdk/acceptance-plan.json": "5b046e6e30802bbe66d837030ae3c215d6fd401d524d48f51302269450d65d94", + "examples/omniroute-codex-sdk/rerun-plan.json": "3f4e9c441ca1b34c9a425cc3e8344e979b99757370506970fd7f760ac55d8730" + }, + "fixture": { + "post_run_sha256": { + "math.js": "5b63136552577a64d788dc3cd4552739d0d60f9e1adb63ec4dfb6932d56fc75d", + "math.test.js": "0a60a61022b4d9333882981dda4d09faf41cc36fd2e9406921fdf6e77b8821de", + "package.json": "7fa8fd86ba4b048bc7395cece337513c65936af275348074eadb443614b387d6" + }, + "unchanged": true, + "oracle_source_unchanged": true + }, + "integration_checks": { + "classification": "Locally authored integration checks using the pinned native app-server and loopback SSE fixtures; not unchanged upstream acceptance.", + "full_before_compact_cli": { + "tests": 12, + "exit_code": 0, + "duration_seconds": 15.595 + }, + "focused_after_compact_cli": { + "tests": 4, + "exit_code": 0, + "duration_seconds": 3.034 + }, + "upstream_suite_scope": "Earlier unchanged upstream suite results remain historical separate evidence; no new full-upstream-suite claim." + }, + "readiness": { + "initial_compact": { + "status": "ready", + "bytes": 1361, + "records": 1, + "enabled_skills": 169, + "scope": "Before spawn-default repair; native catalog discovery only." + }, + "repaired": { + "event": "result", + "requested_model": "cx/gpt-6.1-sol-max", + "requested_effort": "max", + "provider": "omniroute_runtime", + "model_inference_submitted": false, + "usage_status": "unknown", + "usage_scope": null, + "usage": null, + "preflight": true, + "evidence_scope": "native_catalog_discovery", + "native_runtime": { + "name": "omniroute_codex_runtime_worker", + "version": "0.159.2", + "metadata_source": "userAgent" + }, + "effective_config": { + "model": "cx/gpt-6.1-sol-max", + "model_provider": "omniroute_runtime", + "model_reasoning_effort": "max" + }, + "agent_defaults": { + "enabled": true, + "max_concurrent_threads_per_session": 3, + "default_subagent_model": null, + "default_subagent_reasoning_effort": null + }, + "configured_roles": [ + { + "name": "runtime-judge" + } + ], + "mcp_servers": [ + { + "name": "context-mode", + "configured": true, + "enabled": true, + "runtime_status": null, + "auth_status": "unsupported", + "tools_error": false, + "tool_count": 9, + "catalog_ready": true + }, + { + "name": "serena", + "configured": true, + "enabled": true, + "runtime_status": null, + "auth_status": "unsupported", + "tools_error": false, + "tool_count": 5, + "catalog_ready": true + } + ], + "skills": { + "total_count": 169, + "enabled_count": 169, + "required": { + "using-superpowers": true + } + }, + "skill_error_count": 0, + "requirements": { + "mcp": [ + "context-mode" + ], + "skills": [ + "using-superpowers" + ], + "unavailable_mcp": [], + "unavailable_skills": [] + }, + "status": "ready", + "cleanup_status": "closed" + }, + "missing_mcp": { + "exit_code": 2, + "status": "unavailable", + "cleanup_status": "closed", + "usage_status": "unknown", + "usage": null, + "model_inference_submitted": false, + "requirements": { + "mcp": [ + "no-such-runtime-server" + ], + "skills": [], + "unavailable_mcp": [ + "no-such-runtime-server" + ], + "unavailable_skills": [] + } + }, + "missing_skill": { + "exit_code": 2, + "status": "unavailable", + "cleanup_status": "closed", + "usage_status": "unknown", + "usage": null, + "model_inference_submitted": false, + "requirements": { + "mcp": [], + "skills": [ + "no-such-runtime-skill" + ], + "unavailable_mcp": [], + "unavailable_skills": [ + "no-such-runtime-skill" + ] + } + }, + "scope": "Native catalogs and typed config/read, no model turn; runtimeStatus:null remains unknown. Observer saw no SDK provider request before the model trial. The private home also sees native global skill directories." + }, + "native_execution": { + "requested_model": "cx/gpt-6.1-sol-max", + "requested_effort": "max", + "provider": "omniroute_runtime", + "model_inference_submitted": true, + "usage_status": "reported", + "usage_scope": "native_thread_cumulative", + "usage": { + "scope": "See native_threads latest_cumulative_usage; each thread counted once.", + "status": "reported" + }, + "native_runtime": { + "name": "omniroute_codex_runtime_worker", + "version": "0.159.2", + "metadata_source": "serverInfo" + }, + "thread_mode": "started", + "status": "completed", + "duration_ms": 181548, + "item_counts": { + "userMessage": 1, + "commandExecution": 1, + "reasoning": 6, + "mcpToolCall": 3, + "subAgentActivity": 2, + "collabAgentToolCall": 1, + "agentMessage": 1 + }, + "final_marker": "ENHANCED_RUNTIME_ACCEPTED", + "private_original_sha256": "02da6a94913d592bd3c0e3a7171b3df098893b0730f5561897652c09c920a9f0", + "skill_read": [ + { + "command": "/bin/bash -lc 'rtk proxy cat .agents/skills/using-superpowers/SKILL.md'", + "exitCode": 0, + "status": "completed", + "returned_output_sha256": "82c5c8866ad7f5dd4440ce66bd7806ba48a2f13771beae5cf112e53f08fe36ba" + } + ], + "mcp_execution": [ + { + "server": "serena", + "tool": "initial_instructions", + "status": "completed", + "error": null, + "durationMs": 18, + "returned_result_sha256": "e79e20dfa46793983cf0c2168b7428f841618322b9c7f34e9c3c19a491b6795a" + }, + { + "server": "context-mode", + "tool": "ctx_execute", + "status": "completed", + "error": null, + "durationMs": 396, + "returned_result_sha256": "595775ad7c743a984e889d75d656dc267e3c8668a777cdff425287b39b63a389", + "returned_contract_output": null + }, + { + "server": "serena", + "tool": "get_symbols_overview", + "status": "completed", + "error": null, + "durationMs": 36, + "returned_result_sha256": "3771099affe513ed811966ad18b8b25f1cf179743538933548ad3e468d754873", + "returned_contract_output": { + "_meta": null, + "content": [ + { + "type": "text", + "text": "{\"Function\": [\"add\"]}" + } + ], + "structuredContent": { + "result": "{\"Function\": [\"add\"]}" + } + } + } + ], + "cleanup_status": "closed", + "native_threads": [ + { + "scope": "deadline300-parent", + "model_provider": "omniroute_runtime", + "model": "cx/gpt-6.1-sol-max", + "effort": "max", + "sandbox_policy": { + "type": "read-only" + }, + "approval_policy": "never", + "terminal_event": "turn_aborted", + "latest_cumulative_usage": { + "input_tokens": 209699, + "cached_input_tokens": 178816, + "cache_write_input_tokens": 0, + "output_tokens": 3365, + "reasoning_output_tokens": 1625, + "total_tokens": 213064 + }, + "spawn_calls": [ + { + "agent_type": "runtime-judge", + "fork_turns": "none" + }, + { + "agent_type": "runtime-judge", + "fork_turns": "none", + "model": "gpt-6-astra", + "reasoning_effort": "max" + } + ], + "private_original_sha256": "84e39181b74d74d2f28a1bdbe1f76224a43bd03d43b79f6e52b5f8ab441997a4" + }, + { + "scope": "deadline300-judge", + "model_provider": "omniroute_runtime", + "model": "cx/gpt-6-astra-max", + "effort": "max", + "sandbox_policy": { + "type": "read-only" + }, + "approval_policy": "never", + "terminal_event": "task_complete", + "latest_cumulative_usage": { + "input_tokens": 105465, + "cached_input_tokens": 76160, + "cache_write_input_tokens": 0, + "output_tokens": 1908, + "reasoning_output_tokens": 1050, + "total_tokens": 107373 + }, + "spawn_calls": [], + "private_original_sha256": "e1a65718928923fb987983a34dc7705497f26fc34af62741747349460547f491", + "role": "runtime-judge" + }, + { + "scope": "repaired-parent", + "model_provider": "omniroute_runtime", + "model": "cx/gpt-6.1-sol-max", + "effort": "max", + "sandbox_policy": { + "type": "read-only" + }, + "approval_policy": "never", + "terminal_event": "task_complete", + "latest_cumulative_usage": { + "input_tokens": 151525, + "cached_input_tokens": 131712, + "cache_write_input_tokens": 0, + "output_tokens": 2288, + "reasoning_output_tokens": 1122, + "total_tokens": 153813 + }, + "spawn_calls": [ + { + "agent_type": "runtime-judge", + "fork_turns": "none" + } + ], + "private_original_sha256": "e498fe016bf340e5cf5d80267377fd38dfe60d8bd61347619acaffe726fc685b" + }, + { + "scope": "repaired-judge", + "model_provider": "omniroute_runtime", + "model": "cx/gpt-6-astra-max", + "effort": "max", + "sandbox_policy": { + "type": "read-only" + }, + "approval_policy": "never", + "terminal_event": "task_complete", + "latest_cumulative_usage": { + "input_tokens": 64556, + "cached_input_tokens": 61952, + "cache_write_input_tokens": 0, + "output_tokens": 1488, + "reasoning_output_tokens": 878, + "total_tokens": 66044 + }, + "spawn_calls": [], + "private_original_sha256": "762481faf13375f3a11a4ffe24dc48936ed44ba925a806f36ea7126b9626dfb1", + "role": "runtime-judge" + } + ], + "oracle_returns": [ + { + "scope": "deadline300-judge", + "command": "rtk npm test", + "exit_code": 0, + "wall_time_seconds": 0.205897791, + "returned_output_artifact": "evidence/artifacts/omniroute-runtime-enhancements-20260930/deadline300-judge-oracle-output.txt" + }, + { + "scope": "repaired-judge", + "command": "rtk npm test", + "exit_code": 0, + "wall_time_seconds": 0.106420631, + "returned_output_artifact": "evidence/artifacts/omniroute-runtime-enhancements-20260930/repaired-judge-oracle-output.txt" + } + ], + "dagu_runs": [ + { + "attempt": 1, + "status_native_code": 2, + "startedAt": "2026-09-30T15:04:09-04:00", + "finishedAt": "2026-09-30T15:04:10-04:00", + "nodes": [ + { + "name": "readiness", + "status_native_code": 2, + "error": "exit status 2", + "doneCount": 1 + }, + { + "name": "worker", + "status_native_code": 3, + "error": "upstream failed", + "doneCount": null + } + ], + "private_original_sha256": "a95dc6827d1c7f2ba335f1900997ed7700466428c4b19840806679b67f363150" + }, + { + "attempt": 2, + "status_native_code": 2, + "startedAt": "2026-09-30T15:14:17-04:00", + "finishedAt": "2026-09-30T15:19:21-04:00", + "nodes": [ + { + "name": "readiness", + "status_native_code": 4, + "error": null, + "doneCount": 1 + }, + { + "name": "worker", + "status_native_code": 2, + "error": "exit status 2", + "doneCount": 1 + } + ], + "private_original_sha256": "deefed177523529011002411c8bf4ba767510e672f7e1436236622957c16f7fd" + }, + { + "attempt": 3, + "status_native_code": 4, + "startedAt": "2026-09-30T15:25:17-04:00", + "finishedAt": "2026-09-30T15:28:23-04:00", + "nodes": [ + { + "name": "readiness", + "status_native_code": 4, + "error": null, + "doneCount": 1 + }, + { + "name": "worker", + "status_native_code": 4, + "error": null, + "doneCount": 1 + } + ], + "private_original_sha256": "f63a5b3560a5d9b45f43e266b4d2d9619286767ccffc8cf08e2718df68ac80ea" + } + ] + }, + "independent_observation": { + "original_sha256": "6961a59ade6632a9c9a091f7d2abaaa1b45d1103a2ff6a8954d8ce101b197569", + "event_counts": { + "request": 23, + "response_headers": 23, + "response_completed": 21, + "flow_error": 23 + }, + "request_groups": [ + { + "scope": "provider-request-group-1", + "requested_model": "cx/gpt-6.1-sol-max", + "effort": "max", + "request_count": 10, + "response_completed_count": 8, + "flow_error_count": 10, + "completed_response_usage_sum": { + "input_tokens": 209699, + "output_tokens": 3365, + "total_tokens": 213064, + "cached_input_tokens": 178816, + "reasoning_output_tokens": 1625 + }, + "http_status_counts": { + "200": 10 + } + }, + { + "scope": "provider-request-group-2", + "requested_model": "cx/gpt-6-astra-max", + "effort": "max", + "request_count": 4, + "response_completed_count": 4, + "flow_error_count": 4, + "completed_response_usage_sum": { + "input_tokens": 105465, + "output_tokens": 1908, + "total_tokens": 107373, + "cached_input_tokens": 76160, + "reasoning_output_tokens": 1050 + }, + "http_status_counts": { + "200": 4 + } + }, + { + "scope": "provider-request-group-3", + "requested_model": "cx/gpt-6.1-sol-max", + "effort": "max", + "request_count": 6, + "response_completed_count": 6, + "flow_error_count": 6, + "completed_response_usage_sum": { + "input_tokens": 151525, + "output_tokens": 2288, + "total_tokens": 153813, + "cached_input_tokens": 131712, + "reasoning_output_tokens": 1122 + }, + "http_status_counts": { + "200": 6 + } + }, + { + "scope": "provider-request-group-4", + "requested_model": "cx/gpt-6-astra-max", + "effort": "max", + "request_count": 3, + "response_completed_count": 3, + "flow_error_count": 3, + "completed_response_usage_sum": { + "input_tokens": 64556, + "output_tokens": 1488, + "total_tokens": 66044, + "cached_input_tokens": 61952, + "reasoning_output_tokens": 878 + }, + "http_status_counts": { + "200": 3 + } + } + ], + "usage_scope": "Derived sum of actual returned usage for nonoverlapping completed flows within each request/cache scope. Cache and reasoning counters are subsets. Separate corroboration of native thread counters; no whole-task coverage, savings, backend or billing attestation." + }, + "failures": { + "first_port": { + "port": 25283, + "exit_code": 1, + "reason": "Address already in use; selected a free owned loopback port without stopping another process." + }, + "native_config_doctor": { + "exit_code": 1, + "config_load": "ok", + "scope": "Default native OpenAI auth not provided in this new private home; the SDK's process-scoped OmniRoute route was not present in doctor. Not a full doctor pass or an account-absence claim." + }, + "initial_native_test_attempts": [ + { + "attempt": 1, + "exit_code": 1, + "reason": "TransportClosedError before explicit start." + }, + { + "attempt": 2, + "exit_code": 1, + "reason": "Missing serverInfo metadata after start; required source-backed normalization." + } + ], + "first_graph": { + "cli_exit_code": 1, + "readiness_exit_code": 2, + "worker": "aborted", + "reason": "Task binding exports excluded by native Dagu environment filter; no model submitted." + }, + "second_graph": { + "cli_exit_code": 1, + "worker_exit_code": 2, + "sdk_return": { + "status": "deadline_exceeded", + "cleanup_status": "closed", + "interrupt_status": "requested", + "usage_status": "unknown", + "usage": null, + "model_inference_submitted": true + }, + "reason": "Readiness/MCP and native judge oracle passed, but parent exceeded300 seconds; component success did not qualify graph completion." + }, + "cooperation_followup": { + "native_model": "Claude Opus5.5", + "effort": "max", + "completed": false, + "stop_exit_code": 0, + "usage_status": "unknown", + "scope": "Only owned follow-up session stopped; no new confirmed owner SendMessage or approval." + } + }, + "correction_log": [ + { + "mistake": "Assumed low-level initialize starts the client.", + "correction": "Explicit public start() precedes initialize().", + "verification": "First transport-closed test failure, pinned async_client.py and subsequent actual native checks." + }, + { + "mistake": "Expected low-level initialize to populate serverInfo name/version.", + "correction": "Prefer populated serverInfo; fill absent metadata from native userAgent and validate exact native version.", + "verification": "Original initialize return and pinned client/api/_initialize_metadata source; Astra review after one bounded Sol repair." + }, + { + "mistake": "Treated SDK launch profile as effective app-server configuration.", + "correction": "Use worker-home base config plus supported process overrides.", + "verification": "Pinned Codex CLI app-server LoaderOverrides::default() and native config/read." + }, + { + "mistake": "Treated gateway-prefixed default_subagent_model as a native catalog name.", + "correction": "Leave scoped spawn model/effort defaults unset; inherit explicit parent before native role applies Astra gateway alias.", + "verification": "Actual rejected first spawn, pinned child_config ordering, one successful unmodified role spawn in repaired run; Astra acceptance." + }, + { + "mistake": "Expected exported task variables to reach Dagu steps automatically; proposed allow_env key.", + "correction": "Use native root env imports for six task bindings; supported filter key is env_passthrough.", + "verification": "Initial readiness exit2, pinned Dagu filtering/evaluation source, repaired native readiness and complete graph." + }, + { + "mistake": "Expected ordinary RTK filtering to preserve JSONL machine output.", + "correction": "Recover the actual failure result through rtk recall and use rtk proxy uv in the graph.", + "verification": "Retained truncated stdout, recovered original deadline/cleanup fields and complete repaired JSONL." + } + ], + "cleanup": { + "observer_owned_match": true, + "observer_stop_signal": "SIGINT", + "observer_stop_command_exit_code": 0, + "observer_listener_after_stop": false, + "sdk_cleanup_status": "closed", + "other_owners_services_unchanged": true + }, + "retained_private_originals": { + "sdk-preflight-tests-full.log": { + "sha256": "8eaae6c66d3796da82df722019ab160886beb0e364a97625ffce40f27ce9773f", + "bytes": 11060 + }, + "sdk-preflight-tests-after-start-full.log": { + "sha256": "fba9d77170997a6ca1d23978edab4c84fac7ce61dea0b653770ed3c5d7615f11", + "bytes": 11608 + }, + "sdk-preflight-tests-after-metadata-normalization-full.log": { + "sha256": "a0afe8542eb408db54e9789fbd5c1c79251e8ca886dc167041525ae9c377359b", + "bytes": 6189 + }, + "sdk-native-initialize-metadata.log": { + "sha256": "63b710a5cc8d819c74060a35ec8ca2e762ac038ae88f99e413e0073b2d8047b3", + "bytes": 126 + }, + "sdk-enhanced-worker-full-tests-original.log": { + "sha256": "d923fb43bd72040028fff23dd287e4ccd06bd407604e5a14f963001d22c6aa45", + "bytes": 1955 + }, + "sdk-enhanced-worker-compact-cli-tests-original.log": { + "sha256": "90edf09b885292634a3c9a4e35eaf1963e5eaf64cafc399dd2afd72b6c1440f6", + "bytes": 2237 + }, + "enhancement-preflight-negative.json": { + "sha256": "a9e3f82db007fbf7b223e5160c1cc481262cab3579dbf649fcf2a1b15d6ed7d4", + "bytes": 23771 + }, + "enhancement-preflight-negative-skill.jsonl": { + "sha256": "5ac66368c42b7121042fe8a0e7690b6634d7d44b50e2a70eb7bedd32f401bde8", + "bytes": 23767 + }, + "enhancement-preflight-compact.jsonl": { + "sha256": "b2787b3f10a773c383a4e147b35034bb5ea2fddd3e7281caf916ce4f99974a33", + "bytes": 1361 + }, + "enhancement-dagu.log": { + "sha256": "5117ae8830dc3cb7b499b6d16a737c4ca9acca4e0b6a78563eb245fb2d1bdc3b", + "bytes": 1075 + }, + "enhancement-dagu.stderr": { + "sha256": "6f0ce24c50eb4a44f7934fbb85ad347defe561ad524e536b59efa36d7d076f36", + "bytes": 1017 + }, + "enhancement-dagu-after-env-import.log": { + "sha256": "df80ba2aa573178a5becab8f2ffd259f06b673f06ed496904868ab906c67be62", + "bytes": 3300 + }, + "enhancement-dagu-after-env-import.stderr": { + "sha256": "1aeddce5ee9dd14a998b7b65e9a6d09ff8bd8b6db63225f7c151a47269341eaf", + "bytes": 1188 + }, + "enhancement-failed-sdk-recovered.jsonl": { + "sha256": "571c2a17f62d592392a25cecd414389726fc6a0b837a70a6d16f769fd0cc228d", + "bytes": 986 + }, + "enhancement-native-result-repaired.json": { + "sha256": "02da6a94913d592bd3c0e3a7171b3df098893b0730f5561897652c09c920a9f0", + "bytes": 26215 + }, + "enhancement-dagu-after-spawn-repair.stderr": { + "sha256": "3290f97fd0889761f23a4951e1406ae986434d8fb0bbc33b44a777f243ebf16a", + "bytes": 917 + }, + "repaired-sdk-stdout": { + "sha256": "b0ab3c35e61035f3637b4cb0385362b7b6767fa1d3e852befb2886e6d83e0453", + "bytes": 2214 + }, + "repaired-dagu-readiness": { + "sha256": "97283f651d6564347ded4dae209be3160d5035cdc6b2185cdd1a6a98802c2259", + "bytes": 1335 + } + }, + "evidence_policy": "Public fields are sanitized selections of actual returned metadata, commands and oracle output plus independent observation; full original native transcripts remain private. Consistency validation does not certify truth." +} diff --git a/examples/omniroute-codex-sdk/README.md b/examples/omniroute-codex-sdk/README.md index c1cbb43af..165e1bc6e 100644 --- a/examples/omniroute-codex-sdk/README.md +++ b/examples/omniroute-codex-sdk/README.md @@ -1,5 +1,10 @@ # Native Codex SDK worker through OmniRoute +For task-selected MCP, native child agents and automation, use the +[native enhancement kit](enhancements.md) and its metadata readiness gate. +The [bounded live acceptance](../../evidence/receipts/omniroute-runtime-enhancements-20260930.json) +covers selected skill/MCP use, one Astra/Max judge and a completed Dagu graph. + This foundation worker can be called from a native Claude coordinator. It uses the maintained Codex harness through the official Python SDK, with Sol/max as the primary worker and an invocation-scoped OmniRoute Responses provider. diff --git a/examples/omniroute-codex-sdk/acceptance-plan.json b/examples/omniroute-codex-sdk/acceptance-plan.json new file mode 100644 index 000000000..434081aa4 --- /dev/null +++ b/examples/omniroute-codex-sdk/acceptance-plan.json @@ -0,0 +1,27 @@ +{ + "schema_version": 1, + "kind": "bounded_native_acceptance_plan", + "lane": "foundation", + "sources": { + "codex": "openai/codex@ff6aec96948b70d94983af2641a6b67c94faeff5", + "dagu": "dagucloud/dagu@58fed633d58c1dd1319091fdb2c2f6158ecfa053", + "context_mode": "mksglu/context-mode@589d8214d56740a28b5f7bf63167743d586b0b40" + }, + "before_provider_execution": true, + "quality_contract": [ + "Typed native preflight must discover the selected skill and nonempty Context Mode tool catalog without creating a model turn.", + "Missing required skill/server must return nonzero; discovery must not print configuration/credentials/skill bodies or call MCP tools.", + "Actual task must read the task-relevant using-superpowers body and execute a maintained Context Mode MCP tool.", + "Actual task must dispatch the configured native runtime-judge with gateway-compatible Astra-Max/Max; child must run the unchanged arithmetic oracle and return its exact exit.", + "Native Dagu graph must preserve readiness-before-worker dependency and bound one active run/deadlines; no scheduled-run acceptance without a scheduler.", + "Only the owned fixture/readiness state and private native artifacts may change; arithmetic source/oracle hashes remain unchanged.", + "Preserve failed attempts and unknown usage; keep SDK parent/child/provider response usage scopes distinct without overlapping totals." + ], + "limits": [ + "No universal quality/ranking/token-savings claim.", + "No automatic model-write retry, new global service, scheduler or account route change.", + "No promotion of the failed Claude SDK bridge.", + "MCP catalog readiness, configured role metadata and enabling hook support are distinct from actual tool/agent/hook execution.", + "User-scope native skills may remain visible outside the private CODEX_HOME; this is not complete home isolation." + ] +} diff --git a/examples/omniroute-codex-sdk/agents/runtime-judge.toml b/examples/omniroute-codex-sdk/agents/runtime-judge.toml new file mode 100644 index 000000000..3af93d2d7 --- /dev/null +++ b/examples/omniroute-codex-sdk/agents/runtime-judge.toml @@ -0,0 +1,11 @@ +# Native role configuration, based on examples/codex-native/agents/stack-verifier.toml. +# Source: openai/codex ff6aec96948b70d94983af2641a6b67c94faeff5 +# codex-rs/core/src/agent/role.rs:37 and child_config.rs:130. +# The child retains the live parent provider and native parent sandbox. +name = "runtime-judge" +description = "Inspect a consequential runtime claim from original source and returned evidence; report a verdict without editing." +model = "cx/gpt-6-astra-max" +model_reasoning_effort = "max" +developer_instructions = """ +Verify only the assigned consequential claim from its named source and retained original artifact. Return confirmed, refuted or unverified, with the source path or URL and exact command result when available. Preserve unknown provider usage and account identity as unknown. Read task-relevant skill instructions on demand and process large output through context-mode. Stay within the assigned read-only scope, use the inherited native sandbox, and return inline; never edit, launch another agent, or broaden the task. +""" diff --git a/examples/omniroute-codex-sdk/enhancements.md b/examples/omniroute-codex-sdk/enhancements.md new file mode 100644 index 000000000..f6b37612b --- /dev/null +++ b/examples/omniroute-codex-sdk/enhancements.md @@ -0,0 +1,150 @@ +# Native runtime enhancements + +Use this kit when a Claude coordinator needs an OmniRoute worker with selected +skills, MCP tools, native agents or an automated readiness gate. The official +SDK owns execution, tools, compaction, resume and interruption. The worker retains +Sol/Max on port 20128; native parent sessions retain their accounts. + +## Prepare an owned worker + +Keep the task in its assigned worktree and use a new private Codex home. Install +task-selected skills through the [existing native installer](../../blueprints/runtime-workers/skills/README.md); +`--check-only` verifies installed source identity. Skills are not plugin, MCP, +hook or workflow installations. The broad 136-skill trial remains distinct from +task-specific acceptance. + +Render [runtime.config.template.toml](runtime.config.template.toml) into the new +home's `config.toml`. The existing single-template renderer supports this without +reading a host-value file: + +```sh +rtk proxy python3 -c 'import sys; from pathlib import Path; sys.path.insert(0,"tools/adoption"); from render_config import render_one; print(render_one(Path(sys.argv[1]),dict(zip(("ECO_ROOT","WORKER_STATE"),sys.argv[2:]))),end="")' \ + examples/omniroute-codex-sdk/runtime.config.template.toml \ + "$ECO_ROOT" "$WORKER_STATE" +``` + +Write that output only to the new owned home. Place the supplied +[role](agents/runtime-judge.toml) at `/agents/runtime-judge.toml`. +Use 0700 directories and 0600 configuration/role files. For an existing home, +keep its native tool/plugin/hook configuration and apply only reviewed selected +keys through its native config writer; do not replace its configuration with +this starter. Optional services use their existing native recipes. + +The starter selects maintained Context Mode with a required startup, native +Serena read tools with worker-scoped state, live web search, native hook +support and at most three concurrent child threads. Generic children use Sol/Max; +the bounded consequential judge explicitly uses Astra/Max. The child's native +provider remains the scoped OmniRoute provider. Generic children inherit the +explicit parent model and effort. Leave native `default_subagent_model` and +`default_subagent_reasoning_effort` unset in this scoped kit: spawn validates +default names against its native catalog before applying a role's gateway alias. +Enabling native hooks does not +install a hook or establish that it ran. Adopt hooks/plugins through their own +native installers; Claude's hook format belongs to the Claude coordinator. + +Codex 0.159.2 app-server does not apply the CLI's selected named profile, even +though the SDK exposes launch-argument overrides. Keep selected settings in the +worker home's native configuration and process overrides. A profile flag or +legacy `profile=` key is not a substitute. + +## Check readiness, then execute + +```sh +rtk uv run --locked --script examples/omniroute-codex-sdk/worker.py \ + --workspace "$WORKER_PROJECT" --codex-home "$WORKER_CODEX_HOME" \ + --preflight --require-mcp context-mode --require-skill using-superpowers \ + --timeout 60 +``` + +Add task-required server and skill names with repeated requirement flags. The +metadata-only preflight reports requested and native effective model/provider/effort, +compact skill and MCP discovery, and configured agent names. It emits one compact +record by default; `--catalog-details` exposes the full sanitized discovery catalog +for a diagnostic preflight. It requests no model turn and returns +failure for missing requirements. Its tool catalog is discovery evidence; +nullable native runtime status stays unknown. A real MCP call and native child +task need separate acceptance. + +Use the normal [worker invocation](README.md) after readiness. Keep skill bodies +and tool schemas on demand, preserve native caching and count each thread's +latest cumulative usage once. Preserve a failed run's original return before +selecting retry or fresh recovery. + +## Automate with Dagu + +[runtime-worker.yaml](runtime-worker.yaml) uses maintained Dagu 2.16.6 to run +readiness before one bounded SDK task. Export `STACK_ROOT`, `WORKER_PROJECT`, +`WORKER_CODEX_HOME`, `WORKER_TASK_FILE`, `WORKER_BASE_URL` (normally +`http://127.0.0.1:20128/v1`) and a new private `WORKER_RESULT` path. +The task comes from the owned input file rather than a scheduler prompt. Keep +Dagu's state in its own private directory. The graph explicitly imports these +six task bindings through native root `env`; Dagu filters other inherited +variables before step execution: + +```sh +rtk dagu validate --dagu-home "$WORKER_DAGU_STATE" \ + "$STACK_ROOT/examples/omniroute-codex-sdk/runtime-worker.yaml" +rtk dagu start --context local --dagu-home "$WORKER_DAGU_STATE" \ + --run-id "$WORKER_RUN_ID" \ + "$STACK_ROOT/examples/omniroute-codex-sdk/runtime-worker.yaml" +``` + +One active run, a 600-second worker deadline and a 720-second graph deadline +bound the graph. The commands use `rtk proxy uv` to retain complete JSONL results. +There is no automatic retry +of model writes and no schedule or scheduler installation. The existing +[selected-step recovery recipe](../../blueprints/convergence-practice/job-recovery/README.md) +is separate evidence for deterministic checkpoint reuse. A schedule requires its +own frequency, scheduler lifecycle and observed run. + +## Claude workflows and further tools + +The native Claude coordinator uses the [selected workflow and role recipe](../claude-native/workflows/README.md) +for source research, isolated implementation and independent verification. Its +native Bash stage can dispatch this worker or Dagu graph. Keep explicit +task-matched models, Max effort and role dispatch as that recipe specifies. +Use its supported installer for agents, hooks and workflows, and the native MCP +registration for selected coordinator tools. These parent features do not +automatically transfer into the external SDK process. + +For code navigation, retrieval, browser automation, memory or observability, +choose the relevant existing foundation recipe and require its native server +when needed. A recorded installation or an advertised tool count does not +establish service execution or model-mediated quality. The separate Claude SDK +bridge retains its failed route status. + +## Observed acceptance + +The [September 30 receipt](../../evidence/receipts/omniroute-runtime-enhancements-20260930.json) +records a successful bounded Dagu graph: Sol/Max read the selected skill, called +Context Mode and Serena, and dispatched one Astra/Max judge through the same +OmniRoute provider. The judge ran the unchanged upstream fixture's test exactly +once with exit 0; the parent completed, SDK cleanup closed, and fixture hashes +matched. Independent source and artifact review accepted this integration. + +The [scoped experiment](../../blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json) +retains the initial environment failure and 300-second timeout. The successful +rerun followed [its recorded repair plan](rerun-plan.json). Usage remains separate +per native thread; observer totals corroborate those counters. This acceptance +covers these selected calls and a manual graph run. Installed skills, native +hook support and optional scheduler/tool recipes keep their own execution gates. + +## Primary sources + +- [Codex SDK and typed request API](https://github.com/openai/codex/tree/ff6aec96948b70d94983af2641a6b67c94faeff5/sdk/python), + `AsyncCodexClient.request`, `generated/v2_all.py`, version 0.159.2. +- [Native app-server profile boundary](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/cli/src/main.rs#L1263) + and [child provider inheritance](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/core/src/agent/child_config.rs#L130). +- [Native spawn-default validation order](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/core/src/agent/child_config.rs#L196-L235) + and [role model overrides](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/core/src/agent/role.rs#L177-L191). +- [Native MCP configuration](https://developers.openai.com/codex/mcp), [native agent fields](https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/config/src/config_toml.rs#L478). +- [Context Mode 1.0.169](https://github.com/mksglu/context-mode/tree/589d8214d56740a28b5f7bf63167743d586b0b40), + native stdio entry as reviewed in `adoption/templates/codex.config.template.toml`. +- [Serena selected source](https://github.com/oraios/serena/tree/c6fbd1c5932df2494ffa0020af5a9fbe80b82143), + native `start-mcp-server` integration from the same adoption template; selected + read tools and worker-scoped state do not qualify all language servers. +- [Dagu 2.16.6 native graph example](https://github.com/dagucloud/dagu/blob/58fed633d58c1dd1319091fdb2c2f6158ecfa053/examples/embedded/local/workflow.yaml) + and [native root environment import](https://github.com/dagucloud/dagu/blob/58fed633d58c1dd1319091fdb2c2f6158ecfa053/internal/spec/dag.go#L694-L710). + The repository's pinned native job-recovery recipe qualifies a separate recovery scope. +- [Claude native workflows](https://code.claude.com/docs/en/workflows); the + repository's vendored scripts retain their reviewed agent-lab pins and bytes. diff --git a/examples/omniroute-codex-sdk/rerun-plan.json b/examples/omniroute-codex-sdk/rerun-plan.json new file mode 100644 index 000000000..239c497a6 --- /dev/null +++ b/examples/omniroute-codex-sdk/rerun-plan.json @@ -0,0 +1,24 @@ +{ + "schema_version": 1, + "scope": "Bounded native enhancement acceptance after the preserved 300-second failure", + "original_plan": { + "path": "examples/omniroute-codex-sdk/acceptance-plan.json", + "sha256": "5b046e6e30802bbe66d837030ae3c215d6fd401d524d48f51302269450d65d94" + }, + "trigger": "Dagu readiness passed and actual MCP calls and Astra oracle passed, but the parent turn aborted at its 300-second deadline. The initial spawn had rejected a gateway-prefixed default before loading the role.", + "source": "https://github.com/openai/codex/blob/ff6aec96948b70d94983af2641a6b67c94faeff5/codex-rs/core/src/agent/child_config.rs#L196-L235", + "repairs": [ + "Leave subagent model and effort defaults unset; inherit explicit Sol/Max parent, then apply runtime-judge Astra/Max role.", + "Carry the repository's RTK and on-demand context instructions through native developer_instructions.", + "Keep six explicit Dagu root environment imports, preserve complete JSONL with rtk proxy uv, worker deadline600 and graph deadline720." + ], + "unchanged_contract": [ + "Read the required selected skill body.", + "Use Context Mode ctx_execute to count unchanged test() calls and Serena initial_instructions/get_symbols_overview for math.js.", + "Spawn exactly one native runtime-judge with no redundant model/effort override; observe inherited OmniRoute provider, requested Astra-Max/Max, unchanged rtk npm test exactly once exit0.", + "Require completed parent/native graph and closed local SDK cleanup; preserve a failure rather than promoting component successes.", + "Keep math.js, math.test.js and package.json hashes unchanged. Keep parent/child cumulative counters separate and failed/interrupted usage coverage partial." + ], + "automatic_retry": false, + "scheduler_started": false +} diff --git a/examples/omniroute-codex-sdk/runtime-worker.yaml b/examples/omniroute-codex-sdk/runtime-worker.yaml new file mode 100644 index 000000000..9afcbade7 --- /dev/null +++ b/examples/omniroute-codex-sdk/runtime-worker.yaml @@ -0,0 +1,29 @@ +# Dagu 2.16.6 / 58fed633d58c1dd1319091fdb2c2f6158ecfa053. +# Native graph/run/depends/timeout format from examples/embedded/local/workflow.yaml +# and the existing blueprints/convergence-practice/job-recovery/run.py recipe. +# Export only the task-specific path bindings described in enhancements.md. +type: graph +timeout_sec: 720 +max_active_runs: 1 +env: + - STACK_ROOT: ${STACK_ROOT} + - WORKER_PROJECT: ${WORKER_PROJECT} + - WORKER_CODEX_HOME: ${WORKER_CODEX_HOME} + - WORKER_BASE_URL: ${WORKER_BASE_URL} + - WORKER_RESULT: ${WORKER_RESULT} + - WORKER_TASK_FILE: ${WORKER_TASK_FILE} +steps: + - id: readiness + run: >- + rtk proxy uv run --locked --script "${STACK_ROOT}/examples/omniroute-codex-sdk/worker.py" + --workspace "${WORKER_PROJECT}" --codex-home "${WORKER_CODEX_HOME}" + --base-url "${WORKER_BASE_URL}" + --preflight --require-mcp context-mode --require-skill using-superpowers --timeout 60 + - id: worker + depends: [readiness] + run: >- + rtk proxy uv run --locked --script "${STACK_ROOT}/examples/omniroute-codex-sdk/worker.py" + --workspace "${WORKER_PROJECT}" --codex-home "${WORKER_CODEX_HOME}" + --base-url "${WORKER_BASE_URL}" + --sandbox read-only --timeout 600 --prompt - + --native-result "${WORKER_RESULT}" < "${WORKER_TASK_FILE}" diff --git a/examples/omniroute-codex-sdk/runtime.config.template.toml b/examples/omniroute-codex-sdk/runtime.config.template.toml new file mode 100644 index 000000000..c38e30e2c --- /dev/null +++ b/examples/omniroute-codex-sdk/runtime.config.template.toml @@ -0,0 +1,57 @@ +# Native Codex configuration for a NEW private SDK worker home, not a named profile. +# Source: openai/codex ff6aec96948b70d94983af2641a6b67c94faeff5 +# codex-rs/config/src/config_toml.rs (agents, MCP and hooks); +# codex-rs/cli/src/main.rs:1263 (app-server does not apply --profile). +# Render with tools/adoption/render_config.py as described in enhancements.md. +# The worker supplies its process-scoped provider/model/Max overrides. +model_reasoning_effort = "max" +web_search = "live" +# Native developer instructions carry the repository's RTK/context policy. +# Sources: rtk-ai/rtk v0.50.0 hooks/rtk-awareness-full.md and docs/token-practice.md. +developer_instructions = """ +Read only task-relevant skill bodies and source. Prefix shell commands with rtk; use rtk proxy when machine-readable output or an exact source blob must remain complete. Never prefix shell builtins. Process large output with context-mode and return concise findings with original source or artifact locations. Preserve native caching, compaction and scoped cumulative counters. Stay within the assigned worktree and task; do not broaden the task or change accounts, gateway routes or shared configuration. +""" + +[agents] +enabled = true +max_concurrent_threads_per_session = 3 +# Children inherit the explicit Sol/Max parent/provider. Leave catalog-validated +# spawn defaults unset so a role can apply its gateway alias afterward. +# Source: codex-rs/core/src/agent/child_config.rs:196-235 and role.rs:177-191. + +[agents.runtime-judge] +description = "Inspect a consequential runtime claim from original source and returned evidence; report a verdict without editing." +config_file = "agents/runtime-judge.toml" + +# Maintained context-mode 1.0.169 native stdio entry, adapted from +# adoption/templates/codex.config.template.toml. MCP readiness is required. +[mcp_servers.context-mode] +command = "${ECO_ROOT}/bin/node" +args = ["${ECO_ROOT}/tools/context-mode-1.0.169/lib/node_modules/context-mode/start.mjs"] +startup_timeout_sec = 60 +tool_timeout_sec = 120 +required = true +default_tools_approval_mode = "approve" +disabled_tools = ["ctx_upgrade", "ctx_purge"] + +[mcp_servers.context-mode.env] +RTK_TELEMETRY_DISABLED = "1" +CONTEXT_MODE_PLATFORM = "codex" + +# Native, task-selected code navigation. Require serena explicitly in readiness +# when the task needs it; discovery alone does not qualify a code-navigation run. +# Source: the maintained Codex/Serena native entry in the adoption template. +[mcp_servers.serena] +command = "${ECO_ROOT}/bin/serena" +args = ["start-mcp-server", "--transport", "stdio", "--project-from-cwd", "--context", "codex", "--enable-web-dashboard", "false", "--open-web-dashboard", "false", "--enable-gui-log-window", "false"] +startup_timeout_sec = 60 +tool_timeout_sec = 120 +enabled_tools = ["initial_instructions", "find_symbol", "find_referencing_symbols", "get_symbols_overview", "search_for_pattern"] + +[mcp_servers.serena.env] +SERENA_HOME = "${WORKER_STATE}/serena" + +[features] +hooks = true +daemon_auto_start = false +shell_snapshot = false diff --git a/manifests/evidence.json b/manifests/evidence.json index c83ad78a5..6c6187445 100644 --- a/manifests/evidence.json +++ b/manifests/evidence.json @@ -3728,6 +3728,29 @@ "The gateway pool figures are the cached provider limits (numbers only) of the one account with capacity: 7 of 100 points used before the wave and 11 after it, 22 after the re-check; other sessions may have used points in between." ], "path": "evidence/receipts/cross-family-review-terminal-lane-20260930.json" + }, + { + "id": "omniroute-runtime-enhancements-20260930", + "kind": "native_model_e2e", + "component_ids": [ + "codex", + "omniroute", + "context-mode", + "serena", + "dagu" + ], + "claim": "A scoped native Codex SDK Sol-Max worker completed skill use, selected Context Mode/Serena MCP calls, one Astra-Max native judge and an unchanged oracle through OmniRoute in a successful bounded Dagu graph.", + "limitations": [ + "One unchanged arithmetic fixture and bounded integration; no universal highest-quality model, framework or SDK ranking.", + "169 enabled skills were visible through native discovery. This run read using-superpowers and exercised three selected MCP calls; it does not qualify every installed skill, tool, language server, plugin or hook.", + "Native hook support and live web search are configured, but their execution is unmeasured here. No scheduler, schedule, hook or global account configuration was installed by this kit.", + "Native parent and child cumulative usage are separate scopes. Cached input and reasoning are subsets; observer response counters corroborate the same usage and must not be added. Failed/interrupted and complete provider usage, billing and token savings remain unknown.", + "Each observed completed stream also has an unclassified flow_error record. Native results completed; transport is not described as error-free, and requested model/provider labels are not backend identity attestation.", + "The separate Claude SDK Devin bridge retains its failed/unqualified status. Earlier native Claude-to-SDK acceptance is a historical separate callsite, not a rerun against this source.", + "The follow-up native Claude cooperation session was stopped after no confirmed SendMessage/final packet; no peer approval or new owner-contact count is claimed.", + "The isolated kit is a scoped private worker configuration. Live owners retain shared worker policy, host-wide catalogs/defaults and dashboard checkpoint ownership." + ], + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json" } ], "files": [ @@ -3738,8 +3761,8 @@ }, { "path": ".claude/skills/omniroute-runtime-worker/SKILL.md", - "sha256": "857a00f0c3f4088a20662f32f422b30c4697d0c267c0db1f9dbb95dfcbe39ce5", - "bytes": 2248 + "sha256": "14593cbbbe7a89507c0559dd975dff4a2273a46f0e828a7689f79d650767d28f", + "bytes": 2565 }, { "path": ".gitattributes", @@ -5562,10 +5585,15 @@ "sha256": "de31f07cf4ac3f1d32fc64ef94796a98a9aec39fb2a10945dfd1d13e37cdb246", "bytes": 56660 }, + { + "path": "blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json", + "sha256": "c412bb23594de1003e8aae0e9fad3cf9379de4e5ef63ca09303c36c233ef61f2", + "bytes": 29593 + }, { "path": "blueprints/convergence-practice/omniroute-runtime-workers/experiment.json", - "sha256": "b95c7e1feecf8bdc2a9d315d1dd12551b1636f9ab68ed7ca0b18158efc84a17c", - "bytes": 29454 + "sha256": "6d4812ea4906789e2f55cf206d03863af6116c7137d667d542d2395ac985ce31", + "bytes": 29902 }, { "path": "blueprints/convergence-practice/protocol.json", @@ -35267,6 +35295,46 @@ "sha256": "a3fb9cee8dab79992e1178a684ab264f53a64ade4d1894f28f15c0b8b7a5ba83", "bytes": 23100 }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/deadline300-judge-oracle-output.txt", + "sha256": "b9032a013f9d5b050a0940a2c8142d75ff75d6e560e88e77c58383d4c94fc679", + "bytes": 179 + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime-worker.yaml.txt", + "sha256": "82dd567b9e0fd8cc300b516fed535584472a499f63431ddeb030a36065c91426", + "bytes": 1047 + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/initial-runtime.config.template.toml.txt", + "sha256": "5c023dcf0c9c80a3aaf303dda47a268250c61b054551e3f8ccf213033609c72e", + "bytes": 2183 + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/post-env-import-runtime-worker.yaml.txt", + "sha256": "46cab557d04fcb6bc5ad1be96c5b46d4dd82a8bfc25fe719fb095deb64a7e756", + "bytes": 1282 + }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/repaired-judge-oracle-output.txt", + "sha256": "7b49b6e997017b1cde21f9aa33af3d5510926ad182f3211d0dd40cd71762a44a", + "bytes": 179 + }, + { + "path": "evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-dispatcher.md", + "sha256": "857a00f0c3f4088a20662f32f422b30c4697d0c267c0db1f9dbb95dfcbe39ce5", + "bytes": 2248 + }, + { + "path": "evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-test_worker.py.txt", + "sha256": "ea30d5bd0568f1e179e6460647ef61f2ca1ca025bda574f5f35a315eeee2ae2a", + "bytes": 12585 + }, + { + "path": "evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-worker.py.txt", + "sha256": "8dfa1799dc2ce034548eb2581befe61bef480728cc541a451e960bb48decc651", + "bytes": 11517 + }, { "path": "evidence/artifacts/omniroute-sol-max-20260930/README.md", "sha256": "ecd66ad007aca5ec24223805e98035b5da99284671a65a62dbf799f4aaba2084", @@ -43802,6 +43870,11 @@ "sha256": "a1dd584094ebb8aa1c58da0ac34d1d7b7ddb9fcf5e78b67732c7d3b3a0ba6ce3", "bytes": 6238 }, + { + "path": "evidence/receipts/omniroute-runtime-enhancements-20260930.json", + "sha256": "913b02edf8b557a86a0f16f672a3bcaf8e28609ef608e05a192d1e3cb5c7fb06", + "bytes": 27429 + }, { "path": "evidence/receipts/omniroute-runtime-workers-20260930.json", "sha256": "575af430f95651c425140acbb68cf403692c4d6699d8d89670de0f0728ee291e", @@ -44234,18 +44307,48 @@ }, { "path": "examples/omniroute-codex-sdk/README.md", - "sha256": "17316922e6eddf158641d3cf76294c9a4a6ffb43b33ee6bd5630a0e0b1091ab3", - "bytes": 10526 + "sha256": "b1b48386e9ae9cd9f11841eb08765ad7cf5b68da65fab18a259ac7e487b469df", + "bytes": 10848 + }, + { + "path": "examples/omniroute-codex-sdk/acceptance-plan.json", + "sha256": "5b046e6e30802bbe66d837030ae3c215d6fd401d524d48f51302269450d65d94", + "bytes": 1889 + }, + { + "path": "examples/omniroute-codex-sdk/agents/runtime-judge.toml", + "sha256": "0a0b549d3007c75ccb35be3a1d765de31d0504abdd35dfad1e3d68ad4daead55", + "bytes": 1053 }, { "path": "examples/omniroute-codex-sdk/checks.json", "sha256": "26dab6f4fa94512bbe8965f51fb29845ca07e8c4664765e484cd56bc80f9b610", "bytes": 4632 }, + { + "path": "examples/omniroute-codex-sdk/enhancements.md", + "sha256": "05b325ac018d6cb3124bc519d69a667f5d1b6c5a7390098803680c79bbccc394", + "bytes": 9333 + }, + { + "path": "examples/omniroute-codex-sdk/rerun-plan.json", + "sha256": "3f4e9c441ca1b34c9a425cc3e8344e979b99757370506970fd7f760ac55d8730", + "bytes": 1813 + }, + { + "path": "examples/omniroute-codex-sdk/runtime-worker.yaml", + "sha256": "b3093a32ad708f09b81893f9d65975f9f01f99078976929e82830e6ec1b6a7b4", + "bytes": 1294 + }, + { + "path": "examples/omniroute-codex-sdk/runtime.config.template.toml", + "sha256": "3602da96a99c2cc4a6f211695dcf0b8f46cd408cd10290b8b54537e38f0258d6", + "bytes": 3027 + }, { "path": "examples/omniroute-codex-sdk/test_worker.py", - "sha256": "ea30d5bd0568f1e179e6460647ef61f2ca1ca025bda574f5f35a315eeee2ae2a", - "bytes": 12585 + "sha256": "b31d70450151925ac506e9cd018740e9d3d4ca4529a70f3a9d4f8b845d7e8da8", + "bytes": 26008 }, { "path": "examples/omniroute-codex-sdk/test_worker.py.lock", @@ -44254,8 +44357,8 @@ }, { "path": "examples/omniroute-codex-sdk/worker.py", - "sha256": "8dfa1799dc2ce034548eb2581befe61bef480728cc541a451e960bb48decc651", - "bytes": 11517 + "sha256": "d93e4bb0e54f436d15b6c06375126eba51289f8b1513e5ef52dfacaa8a65a074", + "bytes": 22008 }, { "path": "examples/omniroute-codex-sdk/worker.py.lock", @@ -46434,6 +46537,7 @@ } ], "convergence_records": [ + "blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json", "blueprints/convergence-practice/omniroute-runtime-workers/experiment.json", "blueprints/blind-catalog-convergence/experiment.json", "blueprints/blind-catalog-convergence/memory-experiment.json", From b19f3c2e1a7e02fba11e193768eac9312277f0b2 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 16:01:40 -0400 Subject: [PATCH 13/14] feat(foundation): default Claude dispatch to enhanced native readiness --- .../skills/omniroute-runtime-worker/SKILL.md | 17 +++++-- .../experiment.json | 2 +- .../pre-dispatch-default-skill.md | 46 +++++++++++++++++++ examples/omniroute-codex-sdk/enhancements.md | 4 +- manifests/evidence.json | 17 ++++--- 5 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 evidence/artifacts/omniroute-runtime-enhancements-20260930/pre-dispatch-default-skill.md diff --git a/.claude/skills/omniroute-runtime-worker/SKILL.md b/.claude/skills/omniroute-runtime-worker/SKILL.md index dafe28855..68a487a66 100644 --- a/.claude/skills/omniroute-runtime-worker/SKILL.md +++ b/.claude/skills/omniroute-runtime-worker/SKILL.md @@ -9,16 +9,23 @@ Bash tool. The primary route is `cx/gpt-6.1-sol-max`, with native Max effort. The coordinator retains its native Claude account and model route. Give a writing worker its own worktree, bounded file ownership, an executable -acceptance condition and a configured private Codex home. For MCP, native agents -or automation, follow `examples/omniroute-codex-sdk/enhancements.md` and pass its -readiness check before dispatch. Tell it other workers +acceptance condition and the enhanced private Codex home described in +`examples/omniroute-codex-sdk/enhancements.md`. Use that scoped setup by default; +preserve an existing home's configuration and adopt only reviewed selected keys. +Pass native readiness before dispatch, requiring Context Mode and the selected +skill; require Serena too when the task needs semantic navigation. Tell it other workers are present and that it must preserve their edits. Feed the task on stdin: ```sh -rtk uv run --locked --script examples/omniroute-codex-sdk/worker.py \ +rtk proxy uv run --locked --script examples/omniroute-codex-sdk/worker.py \ --workspace "$WORKER_PROJECT" \ --codex-home "$PRIVATE_WORKER_HOME" \ - --timeout 300 \ + --preflight --require-mcp context-mode --require-skill using-superpowers \ + --timeout 60 && +rtk proxy uv run --locked --script examples/omniroute-codex-sdk/worker.py \ + --workspace "$WORKER_PROJECT" \ + --codex-home "$PRIVATE_WORKER_HOME" \ + --timeout 600 \ --prompt - ``` diff --git a/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json b/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json index acb4f7f6f..17c5836df 100644 --- a/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json +++ b/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json @@ -98,7 +98,7 @@ "sha256": "3f4e9c441ca1b34c9a425cc3e8344e979b99757370506970fd7f760ac55d8730" }, { - "path": ".claude/skills/omniroute-runtime-worker/SKILL.md", + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/pre-dispatch-default-skill.md", "sha256": "14593cbbbe7a89507c0559dd975dff4a2273a46f0e828a7689f79d650767d28f" }, { diff --git a/evidence/artifacts/omniroute-runtime-enhancements-20260930/pre-dispatch-default-skill.md b/evidence/artifacts/omniroute-runtime-enhancements-20260930/pre-dispatch-default-skill.md new file mode 100644 index 000000000..dafe28855 --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-enhancements-20260930/pre-dispatch-default-skill.md @@ -0,0 +1,46 @@ +--- +name: omniroute-runtime-worker +description: Delegate a bounded foundation engineering task from Claude to the native Codex SDK worker through the selected OmniRoute gateway. +--- + +Read `examples/omniroute-codex-sdk/README.md` for invocation and lifecycle details. +Use this project's `examples/omniroute-codex-sdk/worker.py` through Claude's native +Bash tool. The primary route is `cx/gpt-6.1-sol-max`, with native Max effort. +The coordinator retains its native Claude account and model route. + +Give a writing worker its own worktree, bounded file ownership, an executable +acceptance condition and a configured private Codex home. For MCP, native agents +or automation, follow `examples/omniroute-codex-sdk/enhancements.md` and pass its +readiness check before dispatch. Tell it other workers +are present and that it must preserve their edits. Feed the task on stdin: + +```sh +rtk uv run --locked --script examples/omniroute-codex-sdk/worker.py \ + --workspace "$WORKER_PROJECT" \ + --codex-home "$PRIVATE_WORKER_HOME" \ + --timeout 300 \ + --prompt - +``` + +Use the selected gateway's native Responses lane at loopback port 20128. Keep +native caches, tools and project skill discovery intact; load only task-relevant +skill bodies. Install selected skills through the existing runtime-worker skill +recipe, rather than importing the entire catalog into the task prompt. Optional +MCP services use their native configuration and task-specific readiness checks. +Use the coordinator's selected native workflow roles for research, implementation +and verification, and the bounded Dagu graph when the task needs automation. + +Keep returned thread IDs private and use `--resume` for continuation. The latest +thread usage snapshot includes previous turns; count it once. A deadline invokes +native interruption and child cleanup; remote termination and unknown provider +usage remain unverified. Do not automatically replay a failed writing task. + +Use explicit `--model cx/gpt-6-astra-max` for consequential architecture, +conflicting primary evidence, or a failure unresolved after one bounded Sol +repair. Record that trigger and the acceptance result. The separate Claude SDK +bridge remains a trial after its gateway errors; it is not the primary worker. + +Sources: [Claude native project skills](https://code.claude.com/docs/en/skills) +and [official Codex SDK, rust-v0.159.2](https://github.com/openai/codex/tree/ff6aec96948b70d94983af2641a6b67c94faeff5/sdk/python). +Functional scope and retained failures are recorded in +`docs/decisions/2026-09-30-omniroute-runtime-workers.md`. diff --git a/examples/omniroute-codex-sdk/enhancements.md b/examples/omniroute-codex-sdk/enhancements.md index f6b37612b..f913ae8b2 100644 --- a/examples/omniroute-codex-sdk/enhancements.md +++ b/examples/omniroute-codex-sdk/enhancements.md @@ -1,7 +1,7 @@ # Native runtime enhancements -Use this kit when a Claude coordinator needs an OmniRoute worker with selected -skills, MCP tools, native agents or an automated readiness gate. The official +Use this kit by default for foundation OmniRoute workers dispatched by Claude, +with selected skills, MCP tools, native agents and a readiness gate. The official SDK owns execution, tools, compaction, resume and interruption. The worker retains Sol/Max on port 20128; native parent sessions retain their accounts. diff --git a/manifests/evidence.json b/manifests/evidence.json index 6c6187445..8868446ba 100644 --- a/manifests/evidence.json +++ b/manifests/evidence.json @@ -3761,8 +3761,8 @@ }, { "path": ".claude/skills/omniroute-runtime-worker/SKILL.md", - "sha256": "14593cbbbe7a89507c0559dd975dff4a2273a46f0e828a7689f79d650767d28f", - "bytes": 2565 + "sha256": "505b5c176666acc202a348b736838c74c463200ad3f77aa51c3aa3704c5cbb7b", + "bytes": 2999 }, { "path": ".gitattributes", @@ -5587,8 +5587,8 @@ }, { "path": "blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json", - "sha256": "c412bb23594de1003e8aae0e9fad3cf9379de4e5ef63ca09303c36c233ef61f2", - "bytes": 29593 + "sha256": "005582b16d21b0ad7cfa85857d222baf598badc74d929a82b3da7c2b0dd39d55", + "bytes": 29633 }, { "path": "blueprints/convergence-practice/omniroute-runtime-workers/experiment.json", @@ -35315,6 +35315,11 @@ "sha256": "46cab557d04fcb6bc5ad1be96c5b46d4dd82a8bfc25fe719fb095deb64a7e756", "bytes": 1282 }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/pre-dispatch-default-skill.md", + "sha256": "14593cbbbe7a89507c0559dd975dff4a2273a46f0e828a7689f79d650767d28f", + "bytes": 2565 + }, { "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/repaired-judge-oracle-output.txt", "sha256": "7b49b6e997017b1cde21f9aa33af3d5510926ad182f3211d0dd40cd71762a44a", @@ -44327,8 +44332,8 @@ }, { "path": "examples/omniroute-codex-sdk/enhancements.md", - "sha256": "05b325ac018d6cb3124bc519d69a667f5d1b6c5a7390098803680c79bbccc394", - "bytes": 9333 + "sha256": "b72f71251afdcf432bb404cbca5a0a7441c000bcd9b6c8f02c660fa45cea5f59", + "bytes": 9337 }, { "path": "examples/omniroute-codex-sdk/rerun-plan.json", From 0e86cb7e7798b497a43672dc67328a12d2793964 Mon Sep 17 00:00:00 2001 From: Scout Date: Wed, 30 Sep 2026 16:09:16 -0400 Subject: [PATCH 14/14] docs(foundation): preserve exact selected skill manifest for runtime trial --- .../experiment.json | 2 +- .../selected-skills-manifest.json.txt | 4604 +++++++++++++++++ manifests/evidence.json | 9 +- 3 files changed, 4612 insertions(+), 3 deletions(-) create mode 100644 evidence/artifacts/omniroute-runtime-enhancements-20260930/selected-skills-manifest.json.txt diff --git a/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json b/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json index 17c5836df..b84398395 100644 --- a/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json +++ b/blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json @@ -102,7 +102,7 @@ "sha256": "14593cbbbe7a89507c0559dd975dff4a2273a46f0e828a7689f79d650767d28f" }, { - "path": "blueprints/runtime-workers/skills/manifest.json", + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/selected-skills-manifest.json.txt", "sha256": "3bc75e2e29e624de301227da157d427d81f1590526f837bb7a0c4b74f0b65439" }, { diff --git a/evidence/artifacts/omniroute-runtime-enhancements-20260930/selected-skills-manifest.json.txt b/evidence/artifacts/omniroute-runtime-enhancements-20260930/selected-skills-manifest.json.txt new file mode 100644 index 000000000..f47be0f46 --- /dev/null +++ b/evidence/artifacts/omniroute-runtime-enhancements-20260930/selected-skills-manifest.json.txt @@ -0,0 +1,4604 @@ +{ + "schema_version": 1, + "kind": "skills_trial_manifest", + "scope": "project", + "checked_at": "2026-09-27", + "decision_record": "blueprints/runtime-workers/skills/research.md", + "cli": { + "package": "skills", + "version": "1.7.0", + "source": "https://github.com/vercel-labs/skills/tree/v1.7.0", + "tarball": "https://registry.npmjs.org/skills/-/skills-1.7.0.tgz", + "integrity": "sha512-OfePnDft+Xt9/tCoHdCUe5fkM8i+Q3QOSQO53hm7mKtsXyvc+CKOAAliVWZ484HS3cWx+6r+ob0AArixs3jYXw==", + "sha256": "8d1466f792baaee945dae88e05ee403d6f9e78a3ae8dcbf61496035ca274418d", + "install": "npm install --global --prefix /skills-1.7.0 skills@1.7.0", + "env": { + "DISABLE_TELEMETRY": "1" + }, + "lock_path": "$XDG_STATE_HOME/skills/.skill-lock.json when XDG_STATE_HOME is set, else ~/.agents/.skill-lock.json", + "notes": [ + "`check` runs the same code path as `update` and can write; always pass -g for global scope.", + "The global lock's skillFolderHash is the upstream git tree SHA of the skill folder; a tree-URL install at a 40-hex ref stays at that ref on update.", + "DISABLE_TELEMETRY=1 (or DO_NOT_TRACK=1) disables both the telemetry event and the add-time audit call.", + "skills.sh's documented /api/v1 requires a Vercel OIDC token (https://skills.sh/docs/api, read 2026-09-26); discovery uses `skills find ` (the CLI's unauthenticated /api/search) and the site pages, and the raw audit risks behind the page labels come from https://add-skill.vercel.sh/audit?source=&skills=, the endpoint the CLI calls at add time when telemetry is on." + ], + "ref": "7407f3893ad4dceab546ac002c3ef806e4000c73", + "project_lock_path": "/skills-lock.json", + "project_verification": "SKILL.md sha256, source/ref/skillPath identity and gh api pinned source tree_sha; computedHash is a distinct native SHA-256 field." + }, + "trial": { + "status": "trial", + "install_policy": "Broad role-applicable trial through tools/adoption/install_skills.py; no host installation by this build.", + "prune_rule": "Zero proven activations across the completed, instrumented E2E run set => status pruned, retain run IDs/counters/evidence and remove through skills CLI. Incomplete or uninstrumented runs are unknown, never zero.", + "invoke_evidence": "README.md#invocation-and-pruning", + "native_acceptance": "pending" + }, + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "scenarios": [ + "planning-and-specs", + "tdd", + "e2e-testing", + "ab-testing-and-evaluation", + "debugging", + "code-review", + "security", + "github-issue-to-pr", + "github-pr-review", + "github-ci-fix", + "github-actions", + "release-notes", + "docs-and-citations", + "research", + "deployment-uv-docker", + "memory" + ], + "skills": [ + { + "name": "add-javadoc", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/add-javadoc", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/add-javadoc", + "tree_sha": "4fab124ceaaa67a393a674384015158e3f50b100", + "skill_md_sha256": "93422a18b7d6a98ed4800c800c9d2a4842dc465454253038d9cc091bd5bd45e1", + "skill_md_bytes": 1166, + "description_chars": 159, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations", + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies domain-specific documentation or integration design guidance backed by the upstream implementation. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/add-javadoc/SKILL.md:1" + }, + { + "name": "agent-browser", + "source": "vercel-labs/agent-browser", + "url": "https://github.com/vercel-labs/agent-browser/tree/d01253d9db28d75080e36da3c1c31ef89454731e/skills/agent-browser", + "ref": "d01253d9db28d75080e36da3c1c31ef89454731e", + "path": "skills/agent-browser", + "tree_sha": "82def67855a0d2aad7794207951820fa5422fdb0", + "skill_md_sha256": "3a7520e64de2dfaa516b6721c001e84e06e3c06a187b82af029ae721540ebfac", + "skill_md_bytes": 3457, + "description_chars": 925, + "upstream_disable_model_invocation": false, + "scenarios": [ + "e2e-testing" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Exercises browser-visible behavior and retains observable QA artifacts for applications and extraction callers. Source: vercel-labs/agent-browser@d01253d9db28d75080e36da3c1c31ef89454731e skills/agent-browser/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "agent-canvas-environment", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/agent-canvas-environment", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/agent-canvas-environment", + "tree_sha": "f86b5b739f7a97afbf53f343beb63824942bcb4d", + "skill_md_sha256": "40562401fb3e07a921f4a1451cc44a4ed6441239c18a4f334791fa6a953f103c", + "skill_md_bytes": 9959, + "description_chars": 230, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers the optional Agent Canvas application environment; useful only on workers given that environment. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/agent-canvas-environment/SKILL.md:1" + }, + { + "name": "agent-creator", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/agent-creator", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/agent-creator", + "tree_sha": "1dd69a47d0bfecf45a52add4cf4081f2afd9bef4", + "skill_md_sha256": "c7321d4a60420cefe8f06b8946d4501f0a6a18352f1f79e9526354266cf0109f", + "skill_md_bytes": 7254, + "description_chars": 330, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Documents native OpenHands agent construction or orchestration APIs instead of a replacement runtime. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/agent-creator/SKILL.md:1" + }, + { + "name": "agent-memory", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/agent-memory", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/agent-memory", + "tree_sha": "7ae7fc4e3658214947c683162df6dce3a910d813", + "skill_md_sha256": "f91fb602088b14732037b54c72de8648dd6c14b4261265eb0e4c87ac43b442bd", + "skill_md_bytes": 2051, + "description_chars": 199, + "upstream_disable_model_invocation": false, + "scenarios": [ + "memory", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Persists reusable repository knowledge or a bounded handoff with a reviewable source artifact. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/agent-memory/SKILL.md:1" + }, + { + "name": "agent-readiness-report", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/onboarding/skills/agent-readiness-report", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/onboarding/skills/agent-readiness-report", + "tree_sha": "77d14adb7d8da1ff94707b5119800ff32643cab4", + "skill_md_sha256": "e11eafa6fa0be079680bf49d7376dddff7261ec353e35a1a070d8d3c9f10b3b1", + "skill_md_bytes": 4477, + "description_chars": 307, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Checks and improves repository instructions and feedback loops for autonomous workers. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/onboarding/skills/agent-readiness-report/SKILL.md:1" + }, + { + "name": "agent-sdk-builder", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/agent-sdk-builder", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/agent-sdk-builder", + "tree_sha": "7c2ce2de2c2e607e53a4cb9980a2dde6a2a49f9a", + "skill_md_sha256": "0085981836b18cd815079936ea7784e575a1def0d77ba41f72d9b2abe7589cab", + "skill_md_bytes": 2849, + "description_chars": 228, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Documents native OpenHands agent construction or orchestration APIs instead of a replacement runtime. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/agent-sdk-builder/SKILL.md:1" + }, + { + "name": "agentic-actions-auditor", + "source": "trailofbits/skills", + "url": "https://github.com/trailofbits/skills/tree/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/agentic-actions-auditor/skills/agentic-actions-auditor", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "path": "plugins/agentic-actions-auditor/skills/agentic-actions-auditor", + "tree_sha": "3c07fa0b66ec665df1b17f5e09ab3e735f627029", + "skill_md_sha256": "b2bdb88d559bc37e6c2c8314e28e7a2eb47e7cdd9da51e77da347d3517326dc0", + "skill_md_bytes": 21743, + "description_chars": 571, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security", + "github-actions" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Checks attacker-controlled workflow inputs reaching AI agents and their credentials. Source: trailofbits/skills@0cc1c73a5e96749ab32d7ea5e14892fafa6972ae plugins/agentic-actions-auditor/skills/agentic-actions-auditor/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "azure-devops", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/azure-devops", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/azure-devops", + "tree_sha": "dee8b13d0bd7e0a49f6ae17d78fd8f1fc4d1c356", + "skill_md_sha256": "df602c5dc300b53b5163806ee6b573dab3126db64b4e7c237ba4ddfbb0c2d5fc", + "skill_md_bytes": 3552, + "description_chars": 201, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers alternate source-control or ticket systems encountered during planning; not counted as GitHub-specific coverage. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/azure-devops/SKILL.md:1" + }, + { + "name": "bitbucket", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/bitbucket", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/bitbucket", + "tree_sha": "459944c2558e7d82bc70f367c6ba084a276de343", + "skill_md_sha256": "b9c7fb63cef358d8a21e8348c8c5290d60acc91c536774b88b7121bee6ff0bd1", + "skill_md_bytes": 2551, + "description_chars": 250, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers alternate source-control or ticket systems encountered during planning; not counted as GitHub-specific coverage. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/bitbucket/SKILL.md:1" + }, + { + "name": "bitbucket-cloud", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/bitbucket-cloud", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/bitbucket-cloud", + "tree_sha": "a54aed17547b26848f508043b2ea24e14339d77a", + "skill_md_sha256": "05fa500943fea4940408098e2411cabaa2d316dabb7a56ceeacad3cd2e59057a", + "skill_md_bytes": 3878, + "description_chars": 245, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers alternate source-control or ticket systems encountered during planning; not counted as GitHub-specific coverage. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/bitbucket-cloud/SKILL.md:1" + }, + { + "name": "bitbucket-data-center", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/bitbucket-data-center", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/bitbucket-data-center", + "tree_sha": "6c5d58d993ee9e27e5d5c8db0b51c225535d16f5", + "skill_md_sha256": "912dd5497f8bd3608b1dea6913732239f6cc1ca7996340884688c46a6c56193f", + "skill_md_bytes": 3634, + "description_chars": 313, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers alternate source-control or ticket systems encountered during planning; not counted as GitHub-specific coverage. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/bitbucket-data-center/SKILL.md:1" + }, + { + "name": "brainstorming", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/brainstorming", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/brainstorming", + "tree_sha": "03d4c6657cd20ba0fce9d270fc688150bd191c3b", + "skill_md_sha256": "a32d2255354775aa124855aa7100cf276bea096fff4ebb3a0edf57be216e6c72", + "skill_md_bytes": 17548, + "description_chars": 198, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Turns requirements into bounded designs or specifications before implementation. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/brainstorming/SKILL.md:1" + }, + { + "name": "build-setup", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/cobol-modernization/skills/build-setup", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/cobol-modernization/skills/build-setup", + "tree_sha": "a20c5d119b1b4ba8a0391c9276196b2d0faaad0a", + "skill_md_sha256": "922b0812ba608d51cf760372293f498818544695fe02c61ce7db593d187b8572", + "skill_md_bytes": 2499, + "description_chars": 158, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "tdd" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers specialized language migrations with test fixtures and explicit transformation steps. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/cobol-modernization/skills/build-setup/SKILL.md:1" + }, + { + "name": "canvas-extension-api", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/canvas-extension-api", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/canvas-extension-api", + "tree_sha": "d801371678229dcbb20d642ec95c5a74fce4ef83", + "skill_md_sha256": "a36bcb91071425b5095b90503f51336951767aec5770873a5c784d57980b6157", + "skill_md_bytes": 17452, + "description_chars": 499, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers the optional Agent Canvas application environment; useful only on workers given that environment. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/canvas-extension-api/SKILL.md:1" + }, + { + "name": "cobol-modernization", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/cobol-modernization/skills/cobol-modernization", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/cobol-modernization/skills/cobol-modernization", + "tree_sha": "d86574828d9f3e5aea2b7066105eb44d9e97715c", + "skill_md_sha256": "551452a767707ba2827fc654475e29d5c3735a6eef152e579decaa52b4e3759d", + "skill_md_bytes": 3363, + "description_chars": 136, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "tdd" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers specialized language migrations with test fixtures and explicit transformation steps. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/cobol-modernization/skills/cobol-modernization/SKILL.md:1" + }, + { + "name": "code-review", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/code-review", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/code-review", + "tree_sha": "bd04e3765993619aae24ccabbd84b94121464334", + "skill_md_sha256": "f4a3bf947db539fbb0467598c7bfed0ef25164278b5a22ad760eff5f78057dee", + "skill_md_bytes": 8455, + "description_chars": 157, + "upstream_disable_model_invocation": false, + "scenarios": [ + "code-review", + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides evidence-grounded change review and feedback handling as explicit lifecycle stages. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/code-review/SKILL.md:1" + }, + { + "name": "code-simplifier", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/code-simplifier", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/code-simplifier", + "tree_sha": "6da51b9d5dee02ec26954c3961cb64bc21b69215", + "skill_md_sha256": "ba5cfc2908e5d7e4a896a88c87294a348f356222e5f7118753ed443c0c3a1116", + "skill_md_bytes": 5033, + "description_chars": 435, + "upstream_disable_model_invocation": false, + "scenarios": [ + "code-review", + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides evidence-grounded change review and feedback handling as explicit lifecycle stages. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/code-simplifier/SKILL.md:1" + }, + { + "name": "codebase-design", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/engineering/codebase-design", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/codebase-design", + "tree_sha": "344e3efc88ee60663b2e989555c2efdb548fbd42", + "skill_md_sha256": "2c20617f87ec8af6a434859f381b2f061a69b530444e74eb39e78bb016a6d1e2", + "skill_md_bytes": 6446, + "description_chars": 265, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "code-review" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides interface and module-boundary criteria for testable caller integrations. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/engineering/codebase-design/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "codeql", + "source": "trailofbits/skills", + "url": "https://github.com/trailofbits/skills/tree/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/static-analysis/skills/codeql", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "path": "plugins/static-analysis/skills/codeql", + "tree_sha": "1490253d767cc2c5e48f1245a681ee59cc52eb4f", + "skill_md_sha256": "1a6d919ff80f83b262daf650552af6eb6d2c32b19d0c529b70efe0c116b675cf", + "skill_md_bytes": 18600, + "description_chars": 751, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies maintained security scanning or finding triage with explicit evidence and false-positive handling. Source: trailofbits/skills@0cc1c73a5e96749ab32d7ea5e14892fafa6972ae plugins/static-analysis/skills/codeql/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "datadog", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/datadog", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/datadog", + "tree_sha": "9fcb3bd5ed49971a98224e69d9d7d92fa49d7727", + "skill_md_sha256": "c67db102d293d21ee9318d51e5da8e86ed2d5ed1d92635a6830552b83c457c7f", + "skill_md_bytes": 2864, + "description_chars": 187, + "upstream_disable_model_invocation": false, + "scenarios": [ + "debugging" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Uses native logs, metrics or deployment state for operational diagnosis when the required service is present. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/datadog/SKILL.md:1" + }, + { + "name": "deno", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/deno", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/deno", + "tree_sha": "521248e905142109eedf85ed8b05d12d7f95c099", + "skill_md_sha256": "6704eb29264daea9cf63af19c216a9d1c0970a094830efedd02e0545feaa65c1", + "skill_md_bytes": 2266, + "description_chars": 232, + "upstream_disable_model_invocation": false, + "scenarios": [ + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides native environment, package or deployment procedures; actual deployment credentials and runtime acceptance remain separate. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/deno/SKILL.md:1" + }, + { + "name": "diagnosing-bugs", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/engineering/diagnosing-bugs", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/diagnosing-bugs", + "tree_sha": "99bd56983e42bc752c52da67f1112e4121781cd1", + "skill_md_sha256": "77f3cf31bc99b2f49af943222526531fcc9fc41d047626d3640e875e85af3e84", + "skill_md_bytes": 8529, + "description_chars": 156, + "upstream_disable_model_invocation": false, + "scenarios": [ + "debugging" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Uses hypothesis-driven diagnosis and root-cause evidence before proposing fixes. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/engineering/diagnosing-bugs/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "diagnosing-superpowers", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/diagnosing-superpowers", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/diagnosing-superpowers", + "tree_sha": "9a975225f7a42de50cd2d43483701b6348f99fd5", + "skill_md_sha256": "5a652f8132cc901eb5ca61f89157839f87a2f20aed037fc7a2b51051bc37cd19", + "skill_md_bytes": 6904, + "description_chars": 375, + "upstream_disable_model_invocation": false, + "scenarios": [ + "debugging", + "ab-testing-and-evaluation" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Diagnoses skill routing and workflow failures; metrics must come from actual worker histories. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/diagnosing-superpowers/SKILL.md:1" + }, + { + "name": "discord", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/discord", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/discord", + "tree_sha": "0759b6e8fa2e5910a180d499939128f2baa108a3", + "skill_md_sha256": "ff1cc68562cddeb1f51289e0f5fe13dd272aa89d2b156624ceb8bc65b01ac23f", + "skill_md_bytes": 4352, + "description_chars": 253, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations", + "memory" + ], + "roles": [ + "orchestration", + "research" + ], + "status": "trial", + "merit_note": "Structures authorized team context, incident evidence or knowledge records; external messages require session authority. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/discord/SKILL.md:1" + }, + { + "name": "dispatching-parallel-agents", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/dispatching-parallel-agents", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/dispatching-parallel-agents", + "tree_sha": "15697cb0726c26a66bff737494e8b5266667ba0c", + "skill_md_sha256": "1968923066f3b707eb01d1992cdf4c42284c3855f70253b9cd5000ff45fca13c", + "skill_md_bytes": 6078, + "description_chars": 106, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies an execution, isolation or delegation step in the development lifecycle; native worker tool availability remains a gate. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/dispatching-parallel-agents/SKILL.md:1" + }, + { + "name": "doc-coauthoring", + "source": "anthropics/skills", + "url": "https://github.com/anthropics/skills/tree/33375500bcea98d610eb30ce10ac4e59b89c390d/skills/doc-coauthoring", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/doc-coauthoring", + "tree_sha": "d9df960e61fe2bafe9183e37de6f9f6b73b74087", + "skill_md_sha256": "2e47d78846faeea4a56e9809c52700087a15a2155a3f293a3efbaded81398ef4", + "skill_md_bytes": 15815, + "description_chars": 428, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides verifiable citations or reader-oriented documentation procedures for worker outputs. Source: anthropics/skills@33375500bcea98d610eb30ce10ac4e59b89c390d skills/doc-coauthoring/SKILL.md:1" + }, + { + "name": "docker", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/docker", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/docker", + "tree_sha": "7e742029273a6cd801c5fd1610bc052e467479b4", + "skill_md_sha256": "d4c69e41982982cf1b71e265fbcaec478030bee0bf627285a48bea3a84373a3a", + "skill_md_bytes": 922, + "description_chars": 183, + "upstream_disable_model_invocation": false, + "scenarios": [ + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides native environment, package or deployment procedures; actual deployment credentials and runtime acceptance remain separate. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/docker/SKILL.md:1" + }, + { + "name": "docx", + "source": "anthropics/skills", + "url": "https://github.com/anthropics/skills/tree/33375500bcea98d610eb30ce10ac4e59b89c390d/skills/docx", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/docx", + "tree_sha": "6e6f5b95c1de6e803cc07b214f5059b074d64e0c", + "skill_md_sha256": "8017469ea95fb7d28225c62daf8e2f3492a7b516fc64c18c28977cbf8980b7fe", + "skill_md_bytes": 6911, + "description_chars": 835, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Handles document or research-report artifacts through the format-specific upstream workflow. Source: anthropics/skills@33375500bcea98d610eb30ce10ac4e59b89c390d skills/docx/SKILL.md:1" + }, + { + "name": "domain-modeling", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/engineering/domain-modeling", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/domain-modeling", + "tree_sha": "388c9822641805ca2dcd5038e68a1d5282437ee5", + "skill_md_sha256": "327a2b50620e2fd70abc6893cd6965e76b20f8d0adb0dc2c8d5eb3845efb643e", + "skill_md_bytes": 3331, + "description_chars": 150, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Turns requirements into bounded designs or specifications before implementation. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/engineering/domain-modeling/SKILL.md:1" + }, + { + "name": "evidence-based-citations", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/evidence-based-citations", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/evidence-based-citations", + "tree_sha": "8b146bdfaa2c21074edf3f3f89e6c322d79d0a56", + "skill_md_sha256": "ebd2645e8e3651218d356c534ebcc453fafbd8b0ca36d9d9e7e7d60790ee7021", + "skill_md_bytes": 3182, + "description_chars": 206, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides verifiable citations or reader-oriented documentation procedures for worker outputs. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/evidence-based-citations/SKILL.md:1" + }, + { + "name": "executing-plans", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/executing-plans", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/executing-plans", + "tree_sha": "899ffeab92be3de6cd9ed0078b32737b18b8c135", + "skill_md_sha256": "f38e8f2ddcf079f65493adc713c1fed78421dfaf5f4dbf6b3a6b2b1d95466e71", + "skill_md_bytes": 20405, + "description_chars": 170, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies an execution, isolation or delegation step in the development lifecycle; native worker tool availability remains a gate. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/executing-plans/SKILL.md:1" + }, + { + "name": "find-skills", + "source": "vercel-labs/skills", + "url": "https://github.com/vercel-labs/skills/tree/7407f3893ad4dceab546ac002c3ef806e4000c73/skills/find-skills", + "ref": "7407f3893ad4dceab546ac002c3ef806e4000c73", + "path": "skills/find-skills", + "tree_sha": "76a98a285cb0434f3d39e1a873823556330e398b", + "skill_md_sha256": "c00eeea0e13e74fe4a9d84ba0a8542205a1b736d65f13134fe1a6647eb14976f", + "skill_md_bytes": 5472, + "description_chars": 303, + "upstream_disable_model_invocation": false, + "scenarios": [ + "research", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Uses the upstream skills directory and CLI to discover installable sources before selecting a capability. Source: vercel-labs/skills@7407f3893ad4dceab546ac002c3ef806e4000c73 skills/find-skills/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "finishing-a-development-branch", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/finishing-a-development-branch", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/finishing-a-development-branch", + "tree_sha": "3b1205aa5038c71946077dd63b9e71b447729e70", + "skill_md_sha256": "8db5a922b242dd4e1bf824cb91c13b3e8d8e8a86d6ceaf7f0774eb9cce909d65", + "skill_md_bytes": 7781, + "description_chars": 101, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-issue-to-pr", + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers source-control state, conflicts and integration steps through native git/GitHub operations. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/finishing-a-development-branch/SKILL.md:1" + }, + { + "name": "fp-check", + "source": "trailofbits/skills", + "url": "https://github.com/trailofbits/skills/tree/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/fp-check/skills/fp-check", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "path": "plugins/fp-check/skills/fp-check", + "tree_sha": "f3f830417667dc3a202b1cb40948bc26ce26ddbf", + "skill_md_sha256": "129223b79b8cb1e7c289c90cbe4ba288d9b210e318a0d1464f319e30329481b3", + "skill_md_bytes": 6747, + "description_chars": 343, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies maintained security scanning or finding triage with explicit evidence and false-positive handling. Source: trailofbits/skills@0cc1c73a5e96749ab32d7ea5e14892fafa6972ae plugins/fp-check/skills/fp-check/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "frontend-design", + "source": "anthropics/skills", + "url": "https://github.com/anthropics/skills/tree/33375500bcea98d610eb30ce10ac4e59b89c390d/skills/frontend-design", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/frontend-design", + "tree_sha": "d79e2a5bb4df4a386c2adcdd9ab8709bba28c3f6", + "skill_md_sha256": "d91970639e9f5c37682ac7ab60094d35f1c7c1f38d731bd56396563aee10c1d3", + "skill_md_bytes": 9390, + "description_chars": 204, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "code-review" + ], + "roles": [ + "coding" + ], + "status": "trial", + "merit_note": "Adds intentional UI design or reusable component-interface criteria to coding work. Source: anthropics/skills@33375500bcea98d610eb30ce10ac4e59b89c390d skills/frontend-design/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "gh-address-comments", + "source": "openai/skills", + "url": "https://github.com/openai/skills/tree/49f948faa9258a0c61caceaf225e179651397431/skills/.curated/gh-address-comments", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "path": "skills/.curated/gh-address-comments", + "tree_sha": "042316bece4a9f832145dcff7d5506e99fe3ecf1", + "skill_md_sha256": "77389eefd3fb6584210668ca8e43f4b8de87e7722ddd953474bc9e24cdfaaedd", + "skill_md_bytes": 1278, + "description_chars": 168, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-pr-review", + "code-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Resolves concrete review feedback using GitHub CLI and authenticated repository state. Source: openai/skills@49f948faa9258a0c61caceaf225e179651397431 skills/.curated/gh-address-comments/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "gh-fix-ci", + "source": "openai/skills", + "url": "https://github.com/openai/skills/tree/49f948faa9258a0c61caceaf225e179651397431/skills/.curated/gh-fix-ci", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "path": "skills/.curated/gh-fix-ci", + "tree_sha": "3f99938c9464393f27cc4cc00e4ba17387517803", + "skill_md_sha256": "7b326b4a2f0f5f85122144628ec02077e48841e0e0e82efce88b3415bcfb7c26", + "skill_md_bytes": 3651, + "description_chars": 313, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-ci-fix" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Diagnoses failing checks or manages stalled CI work; explicit authorization still controls external mutations. Source: openai/skills@49f948faa9258a0c61caceaf225e179651397431 skills/.curated/gh-fix-ci/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "github", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github", + "tree_sha": "02cea5f01bd171145824a074ee680881fcfdc08f", + "skill_md_sha256": "c618546605a8461dfa7d2939c97de409ce7455c262aac4513b2b1b8dd15020e8", + "skill_md_bytes": 4880, + "description_chars": 205, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-issue-to-pr", + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers source-control state, conflicts and integration steps through native git/GitHub operations. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github/SKILL.md:1" + }, + { + "name": "github-actions", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github-actions", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github-actions", + "tree_sha": "1c2cde4572e3fdf3c3196846dba86a4ebd456121", + "skill_md_sha256": "3bc931615299740031ec21eef92a3c1cc1acd91d88d6579c67e8e6021a0c83f0", + "skill_md_bytes": 1888, + "description_chars": 160, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-actions" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies native workflow setup and debugging procedures instead of generated CI guesses. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github-actions/SKILL.md:1" + }, + { + "name": "github-agents-md-maintainer", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github-agents-md-maintainer", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github-agents-md-maintainer", + "tree_sha": "6eeab0e65e71aeeaf21e69d3583c4aab8adf45ce", + "skill_md_sha256": "a117d2f599af00a8b1f890b1cecda2a144cc1e59ae1a0370f5798b97377ec206", + "skill_md_bytes": 11745, + "description_chars": 286, + "upstream_disable_model_invocation": false, + "scenarios": [ + "memory", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Persists reusable repository knowledge or a bounded handoff with a reviewable source artifact. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github-agents-md-maintainer/SKILL.md:1" + }, + { + "name": "github-delivery-watchdog", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github-delivery-watchdog", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github-delivery-watchdog", + "tree_sha": "c90ad6ae786552737e7ab2a011310627c5f0acae", + "skill_md_sha256": "536cb76358c784e882c02d0040fe33fe19038fdf2b9050a94739ec07f760bce9", + "skill_md_bytes": 1952, + "description_chars": 109, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides review dispatch or review API procedures; installation grants no permission to post or merge. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github-delivery-watchdog/SKILL.md:1" + }, + { + "name": "github-issue-to-pr", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github-issue-to-pr", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github-issue-to-pr", + "tree_sha": "a8d0921bfb255e12d6f97754c54d79ac72d9b83d", + "skill_md_sha256": "602425d9c99c774e2b4a31ac816313f3e64171a72ff34dcc6aa50a1c6b14ba6a", + "skill_md_bytes": 17616, + "description_chars": 281, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-issue-to-pr" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides issue intake, implementation or dispatch procedures tied to observable repository state. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github-issue-to-pr/SKILL.md:1" + }, + { + "name": "github-issue-triage", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github-issue-triage", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github-issue-triage", + "tree_sha": "9df1430bf1402390fa7070105b589a87861254ed", + "skill_md_sha256": "eec8e8f6d1c9f41f898f438f037c082476ae3a08f70e609a4458c12c196861e3", + "skill_md_bytes": 3141, + "description_chars": 99, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-issue-to-pr" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides issue intake, implementation or dispatch procedures tied to observable repository state. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github-issue-triage/SKILL.md:1" + }, + { + "name": "github-pr-review", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github-pr-review", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github-pr-review", + "tree_sha": "f4e742826b7154635c79820a1cb015906b260a6d", + "skill_md_sha256": "8b1c2f74dede90bbb7a524b66e991f9eb8ab3068b349ad343ca986668567652c", + "skill_md_bytes": 9137, + "description_chars": 100, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides review dispatch or review API procedures; installation grants no permission to post or merge. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github-pr-review/SKILL.md:1" + }, + { + "name": "github-pr-reviewer", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github-pr-reviewer", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github-pr-reviewer", + "tree_sha": "1f4525915d9d62128ef99f6d646ea02984c4c4d4", + "skill_md_sha256": "d599fc3002a7c97ed946e48b4d7c59c2d3f04d982f9a6460ff0884b9cad8224d", + "skill_md_bytes": 26720, + "description_chars": 262, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides review dispatch or review API procedures; installation grants no permission to post or merge. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github-pr-reviewer/SKILL.md:1" + }, + { + "name": "github-repo-monitor", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github-repo-monitor", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github-repo-monitor", + "tree_sha": "e779e4edf79c281f7c9a35cf586eb6084b5046db", + "skill_md_sha256": "8a51a228f4a372162d0f3545ac44a1ce7a7d6616fab0b00fbdcd19789a85e52c", + "skill_md_bytes": 12247, + "description_chars": 484, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-issue-to-pr" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides issue intake, implementation or dispatch procedures tied to observable repository state. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github-repo-monitor/SKILL.md:1" + }, + { + "name": "github-stale-ci-pr-closer", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/github-stale-ci-pr-closer", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/github-stale-ci-pr-closer", + "tree_sha": "0c4596fbf016454fb1b78e1b79f826ade2a26249", + "skill_md_sha256": "060b136307daf00b908567e2a22e84cd3d8acec3f387668af3b9a82a3fb82aa3", + "skill_md_bytes": 1210, + "description_chars": 73, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-ci-fix" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Diagnoses failing checks or manages stalled CI work; explicit authorization still controls external mutations. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/github-stale-ci-pr-closer/SKILL.md:1" + }, + { + "name": "gitlab", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/gitlab", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/gitlab", + "tree_sha": "29879a030a0dd27de75c2674a242492c9d90a5a6", + "skill_md_sha256": "214c4db1a10ec41b81549e5625312b7d686772fba1258379e30013e3789f7fd7", + "skill_md_bytes": 2164, + "description_chars": 178, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers alternate source-control or ticket systems encountered during planning; not counted as GitHub-specific coverage. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/gitlab/SKILL.md:1" + }, + { + "name": "gitlab-issue-to-mr", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/gitlab-issue-to-mr", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/gitlab-issue-to-mr", + "tree_sha": "42357f9cfc48574ac142cec1f488ed6bb06ce4db", + "skill_md_sha256": "95b4390e73cc3ba60be239a403a50f08c64185a804aeb58589c17806609e6738", + "skill_md_bytes": 18988, + "description_chars": 278, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers alternate source-control or ticket systems encountered during planning; not counted as GitHub-specific coverage. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/gitlab-issue-to-mr/SKILL.md:1" + }, + { + "name": "gpt-researcher", + "source": "assafelovic/gpt-researcher", + "url": "https://github.com/assafelovic/gpt-researcher/tree/0957c301ed06c2a5857b834358c7227c739041d4/skills/gpt-researcher", + "ref": "0957c301ed06c2a5857b834358c7227c739041d4", + "path": "skills/gpt-researcher", + "tree_sha": "0de06325b127246093bf5addc15cdf8ae51d1feb", + "skill_md_sha256": "d6f8d0c19f5c898f4e80a8865da0b0c0f23950394a71f1aa52388ee1e4340d67", + "skill_md_bytes": 317, + "description_chars": 43, + "upstream_disable_model_invocation": false, + "scenarios": [ + "research", + "docs-and-citations" + ], + "roles": [ + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Official minimal MCP caller entrypoint for GPT Researcher; closes tool discovery only, with research quality and tool setup verified separately. Source: assafelovic/gpt-researcher@0957c301ed06c2a5857b834358c7227c739041d4 skills/gpt-researcher/SKILL.md:1" + }, + { + "name": "grill-me", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/productivity/grill-me", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/productivity/grill-me", + "tree_sha": "3df14e2d3a89459bf300614be9247e3ce74798f8", + "skill_md_sha256": "caaf8b8de1684f96e26b28f3c29189db5c89cce4b73e1c93d86164f66ef88637", + "skill_md_bytes": 157, + "description_chars": 51, + "upstream_disable_model_invocation": true, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Turns requirements into bounded designs or specifications before implementation. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/productivity/grill-me/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "handoff", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/productivity/handoff", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/productivity/handoff", + "tree_sha": "2242e8f05424b8c2ae94194a90d97b88d16108ec", + "skill_md_sha256": "7c62de979fdc7ac32fb5ddb2146156c917f80ee070d30fadc9d40343c4b6ed25", + "skill_md_bytes": 894, + "description_chars": 86, + "upstream_disable_model_invocation": true, + "scenarios": [ + "memory", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Persists reusable repository knowledge or a bounded handoff with a reviewable source artifact. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/productivity/handoff/SKILL.md:1" + }, + { + "name": "improve-agent-readiness", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/onboarding/skills/improve-agent-readiness", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/onboarding/skills/improve-agent-readiness", + "tree_sha": "6b8dcd8f430d8faefbee3cc3bcc4450dea68f65f", + "skill_md_sha256": "e34bcd869080b07ac7de88172013562b151d2b74506994b6192765f735ed499c", + "skill_md_bytes": 6657, + "description_chars": 290, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Checks and improves repository instructions and feedback loops for autonomous workers. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/onboarding/skills/improve-agent-readiness/SKILL.md:1" + }, + { + "name": "improve-codebase-architecture", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/engineering/improve-codebase-architecture", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/improve-codebase-architecture", + "tree_sha": "3d35cd438f4067b03c8b3792e038960e4ac11526", + "skill_md_sha256": "d1ac25511a936ff4250a48dbcefda363837d6bb9321b3cba73df99fa37270a75", + "skill_md_bytes": 5993, + "description_chars": 125, + "upstream_disable_model_invocation": true, + "scenarios": [ + "planning-and-specs", + "code-review" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides interface and module-boundary criteria for testable caller integrations. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/engineering/improve-codebase-architecture/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "incident-retrospective", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/incident-retrospective", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/incident-retrospective", + "tree_sha": "f12d464f1cdc9584f5fe9677f2c75119226a09c5", + "skill_md_sha256": "bf99ca3938e3245be78cbb4638cbdea9d38f1f42ad051750a3a52bba92e953dc", + "skill_md_bytes": 3554, + "description_chars": 275, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations", + "memory" + ], + "roles": [ + "orchestration", + "research" + ], + "status": "trial", + "merit_note": "Structures authorized team context, incident evidence or knowledge records; external messages require session authority. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/incident-retrospective/SKILL.md:1" + }, + { + "name": "iterate", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/iterate", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/iterate", + "tree_sha": "7152a93b2b9f725f52c5252d988819fe0030661a", + "skill_md_sha256": "58249391292da7a903f0e91483d959b78d405b77956c13f020df5eab7789495a", + "skill_md_bytes": 15153, + "description_chars": 276, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-ci-fix" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Diagnoses failing checks or manages stalled CI work; explicit authorization still controls external mutations. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/iterate/SKILL.md:1" + }, + { + "name": "iterative-retrieval", + "source": "affaan-m/ECC", + "url": "https://github.com/affaan-m/ECC/tree/2b6e839771e53096d8451a213d40dc64ec8acac0/skills/iterative-retrieval", + "ref": "2b6e839771e53096d8451a213d40dc64ec8acac0", + "path": "skills/iterative-retrieval", + "tree_sha": "1f1e8d67cf41d72acf2315dc7e6edeac0fc231a6", + "skill_md_sha256": "b453b16d3e36174b8487c05ab807d0321a66c2d058812b2ae129d82824183725", + "skill_md_bytes": 6786, + "description_chars": 183, + "upstream_disable_model_invocation": false, + "scenarios": [ + "research", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Refines retrieval in bounded passes so workers obtain the context needed for an implementation or research question. Source: affaan-m/ECC@2b6e839771e53096d8451a213d40dc64ec8acac0 skills/iterative-retrieval/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "jira-issue-to-pr", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/jira-issue-to-pr", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/jira-issue-to-pr", + "tree_sha": "e216374c7bc95f6705707e11a1cc65dda9267964", + "skill_md_sha256": "e5c143d6c0256e7cc1786716d358534701154ff86ea26495c8fa5eacf168ce26", + "skill_md_bytes": 10124, + "description_chars": 679, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-issue-to-pr" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides issue intake, implementation or dispatch procedures tied to observable repository state. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/jira-issue-to-pr/SKILL.md:1" + }, + { + "name": "jupyter", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/jupyter", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/jupyter", + "tree_sha": "ae3ccf3f0bc3ec470f740d9cebed4dfb1b1628b8", + "skill_md_sha256": "11f5663bd9bc329844217cb6d3bacc8f475169080f3d859a36d4d0973bd7128e", + "skill_md_bytes": 1540, + "description_chars": 208, + "upstream_disable_model_invocation": false, + "scenarios": [ + "research", + "ab-testing-and-evaluation" + ], + "roles": [ + "coding", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Supports reproducible notebook execution and inspection for research and extraction evaluation. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/jupyter/SKILL.md:1" + }, + { + "name": "jupyter-notebook", + "source": "openai/skills", + "url": "https://github.com/openai/skills/tree/49f948faa9258a0c61caceaf225e179651397431/skills/.curated/jupyter-notebook", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "path": "skills/.curated/jupyter-notebook", + "tree_sha": "ed23a98404260af659ef6bae9cb734bcfb0ca6c2", + "skill_md_sha256": "62f102e8554b25716dccef0ffab4572d4e3eaf05ccc76562d33a065bc9c521fb", + "skill_md_bytes": 4154, + "description_chars": 237, + "upstream_disable_model_invocation": false, + "scenarios": [ + "research", + "ab-testing-and-evaluation" + ], + "roles": [ + "coding", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Supports reproducible notebook execution and inspection for research and extraction evaluation. Source: openai/skills@49f948faa9258a0c61caceaf225e179651397431 skills/.curated/jupyter-notebook/SKILL.md:1" + }, + { + "name": "kubernetes", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/kubernetes", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/kubernetes", + "tree_sha": "68d887ccaf357723985bae1130706a7145e4d38d", + "skill_md_sha256": "e1c28130b212211c33138e0977e64dc57f368c42d6588e2bd173092cc9d4a96d", + "skill_md_bytes": 1303, + "description_chars": 165, + "upstream_disable_model_invocation": false, + "scenarios": [ + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides native environment, package or deployment procedures; actual deployment credentials and runtime acceptance remain separate. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/kubernetes/SKILL.md:1" + }, + { + "name": "learn-from-code-review", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/learn-from-code-review", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/learn-from-code-review", + "tree_sha": "28da28ac893f281737349c3867b5640ae348b0b4", + "skill_md_sha256": "146a6ec99296501601c2918644cbca54a337cca3290d173ac5ce64a5c62db497", + "skill_md_bytes": 6300, + "description_chars": 308, + "upstream_disable_model_invocation": false, + "scenarios": [ + "memory", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Persists reusable repository knowledge or a bounded handoff with a reviewable source artifact. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/learn-from-code-review/SKILL.md:1" + }, + { + "name": "linear", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/linear", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/linear", + "tree_sha": "3419cdad4edd8d23c9eb5cdafa834ac50be9ef3d", + "skill_md_sha256": "f0a509cc3268de2d716dce1b66de027c91b71d26ca330ab1a59363b169d2ae03", + "skill_md_bytes": 7151, + "description_chars": 205, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers alternate source-control or ticket systems encountered during planning; not counted as GitHub-specific coverage. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/linear/SKILL.md:1" + }, + { + "name": "linear-triage", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/linear-triage", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/linear-triage", + "tree_sha": "8a87f4b44d8fe3f1a78159a64639f68268ef4eec", + "skill_md_sha256": "4a6dfb4a604c995879039bcffa65e38b18083faee57c08d9a8ab876ed5993e87", + "skill_md_bytes": 3045, + "description_chars": 244, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers alternate source-control or ticket systems encountered during planning; not counted as GitHub-specific coverage. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/linear-triage/SKILL.md:1" + }, + { + "name": "mainframe-planning", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/cobol-modernization/skills/mainframe-planning", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/cobol-modernization/skills/mainframe-planning", + "tree_sha": "03983adeb00274f278921eb04bc8d3b4ed3ac1a4", + "skill_md_sha256": "a6e64ed015955951520b69e5e87e0aea6ec2693bacc6af60ba488a0a59c61c96", + "skill_md_bytes": 3057, + "description_chars": 176, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "tdd" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers specialized language migrations with test fixtures and explicit transformation steps. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/cobol-modernization/skills/mainframe-planning/SKILL.md:1" + }, + { + "name": "mainframe-removal", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/cobol-modernization/skills/mainframe-removal", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/cobol-modernization/skills/mainframe-removal", + "tree_sha": "5fa438fb84c8a8208993b094fdcb0ee2bbb8e625", + "skill_md_sha256": "bf0c95e28074dd27c4c2facb31783ef079e9dcb551eec8f84a554e845556f2f3", + "skill_md_bytes": 2082, + "description_chars": 149, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "tdd" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers specialized language migrations with test fixtures and explicit transformation steps. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/cobol-modernization/skills/mainframe-removal/SKILL.md:1" + }, + { + "name": "mcp-builder", + "source": "anthropics/skills", + "url": "https://github.com/anthropics/skills/tree/33375500bcea98d610eb30ce10ac4e59b89c390d/skills/mcp-builder", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/mcp-builder", + "tree_sha": "b866bcfb57b780c10b587c7b543e871a91661ce0", + "skill_md_sha256": "0f4592dcb53cf2b5d6b7febee6b4152018b565551a1c29e3c612f57b218ab295", + "skill_md_bytes": 9092, + "description_chars": 277, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations", + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies domain-specific documentation or integration design guidance backed by the upstream implementation. Source: anthropics/skills@33375500bcea98d610eb30ce10ac4e59b89c390d skills/mcp-builder/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "migration-mapping", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/migration-scoring/skills/migration-mapping", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/migration-scoring/skills/migration-mapping", + "tree_sha": "01541663c7d326717eb97454e8cff37bd907d1af", + "skill_md_sha256": "6b65c7e6b15576bd97506ae0ee10e0a6bbb24ed1b2d5946232b2b9b9a540bca1", + "skill_md_bytes": 2284, + "description_chars": 145, + "upstream_disable_model_invocation": false, + "scenarios": [ + "ab-testing-and-evaluation", + "code-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Adds rubric-driven migration evaluation and reports; plugin hooks are not installed by the skills CLI. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/migration-scoring/skills/migration-mapping/SKILL.md:1" + }, + { + "name": "migration-report", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/migration-scoring/skills/migration-report", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/migration-scoring/skills/migration-report", + "tree_sha": "7080394b2efd3de63a5251d95a1a6d6ac7b1e943", + "skill_md_sha256": "0e61fd550879bd54f25f7c970aaab4f66e9b970142c5d761674e4e8b3e7ed827", + "skill_md_bytes": 3089, + "description_chars": 138, + "upstream_disable_model_invocation": false, + "scenarios": [ + "ab-testing-and-evaluation", + "code-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Adds rubric-driven migration evaluation and reports; plugin hooks are not installed by the skills CLI. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/migration-scoring/skills/migration-report/SKILL.md:1" + }, + { + "name": "migration-scoring", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/migration-scoring/skills/migration-scoring", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/migration-scoring/skills/migration-scoring", + "tree_sha": "d7bb843a85e64349b97add0947677273f79c36ce", + "skill_md_sha256": "46764ec6b66b3d1ebdfcc25c771235b45a4b88fa4467fcb002208996665be0ee", + "skill_md_bytes": 3411, + "description_chars": 139, + "upstream_disable_model_invocation": false, + "scenarios": [ + "ab-testing-and-evaluation", + "code-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Adds rubric-driven migration evaluation and reports; plugin hooks are not installed by the skills CLI. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/migration-scoring/skills/migration-scoring/SKILL.md:1" + }, + { + "name": "modern-python", + "source": "trailofbits/skills", + "url": "https://github.com/trailofbits/skills/tree/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/modern-python/skills/modern-python", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "path": "plugins/modern-python/skills/modern-python", + "tree_sha": "e84fa2b3a076b4333e4cc6187510f2b180eed427", + "skill_md_sha256": "ef774b925eb1d1fc12e4f5ddc3f5ad925ecd795315827447228c70cc44c6170c", + "skill_md_bytes": 10015, + "description_chars": 159, + "upstream_disable_model_invocation": false, + "scenarios": [ + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides native environment, package or deployment procedures; actual deployment credentials and runtime acceptance remain separate. Source: trailofbits/skills@0cc1c73a5e96749ab32d7ea5e14892fafa6972ae plugins/modern-python/skills/modern-python/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "news-digest", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/news-digest", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/news-digest", + "tree_sha": "0992f4bc12fbc02444662a3870abe0a755ad1b5f", + "skill_md_sha256": "833aace23ab5b4a5fc44aec71962d1cc0ae88172c4c7659052b3c7f1ada9cf5c", + "skill_md_bytes": 12278, + "description_chars": 319, + "upstream_disable_model_invocation": false, + "scenarios": [ + "research" + ], + "roles": [ + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Defines deduplicated feed collection and dated source summaries for recurring research. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/news-digest/SKILL.md:1" + }, + { + "name": "notion", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/notion", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/notion", + "tree_sha": "f9d670bf2279e7da84fc7da6276cb3854ac9d64e", + "skill_md_sha256": "2ae4b3833a31781501c64e50ecfdda7c1abff34cc33687b039737a2731ab7ac7", + "skill_md_bytes": 3786, + "description_chars": 157, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations", + "memory" + ], + "roles": [ + "orchestration", + "research" + ], + "status": "trial", + "merit_note": "Structures authorized team context, incident evidence or knowledge records; external messages require session authority. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/notion/SKILL.md:1" + }, + { + "name": "npm", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/npm", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/npm", + "tree_sha": "34c1b85200cd6c5629b9c3b997a928aaa8a9e307", + "skill_md_sha256": "f29251d112f6ba935eed0b36ccae2696f9080bdeb7fd852846f729161f7e30f2", + "skill_md_bytes": 440, + "description_chars": 165, + "upstream_disable_model_invocation": false, + "scenarios": [ + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides native environment, package or deployment procedures; actual deployment credentials and runtime acceptance remain separate. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/npm/SKILL.md:1" + }, + { + "name": "openhands-api", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/openhands-api", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/openhands-api", + "tree_sha": "eaec51032ac36cf864f0079bd67698bf41adec04", + "skill_md_sha256": "f0124b4e04066b3b575d7d11c93aaac16014df7e1eeaaff03383b1b26613259e", + "skill_md_bytes": 18282, + "description_chars": 184, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Documents native OpenHands agent construction or orchestration APIs instead of a replacement runtime. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/openhands-api/SKILL.md:1" + }, + { + "name": "openhands-automation", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/openhands-automation", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/openhands-automation", + "tree_sha": "7c5f5a3d5317e187eb9b95d407570a6e93ce989b", + "skill_md_sha256": "b6201e8cd9900476cb14ccc60f92bcb3c3a61847a6bad3cb259d95f385e09a28", + "skill_md_bytes": 40915, + "description_chars": 261, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Documents native OpenHands agent construction or orchestration APIs instead of a replacement runtime. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/openhands-automation/SKILL.md:1" + }, + { + "name": "openhands-enterprise-troubleshooting", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/openhands-enterprise-troubleshooting", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/openhands-enterprise-troubleshooting", + "tree_sha": "bbe40867eeaa2d890a57df32331003d35ea0635a", + "skill_md_sha256": "b7baa048b8fbcbb971dd0be8d96104689091b58304ffea276819ad0fabd51382", + "skill_md_bytes": 15206, + "description_chars": 510, + "upstream_disable_model_invocation": false, + "scenarios": [ + "debugging" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Uses native logs, metrics or deployment state for operational diagnosis when the required service is present. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/openhands-enterprise-troubleshooting/SKILL.md:1" + }, + { + "name": "openhands-sdk", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/openhands-sdk", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/openhands-sdk", + "tree_sha": "65f0af3cda9aa9df67f7e65b7276408cb457d531", + "skill_md_sha256": "033b9e64ec7639f4b793dc1fbf856757ac35dad096e0efc795f27872aa920a97", + "skill_md_bytes": 27349, + "description_chars": 288, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Documents native OpenHands agent construction or orchestration APIs instead of a replacement runtime. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/openhands-sdk/SKILL.md:1" + }, + { + "name": "pdf", + "source": "anthropics/skills", + "url": "https://github.com/anthropics/skills/tree/33375500bcea98d610eb30ce10ac4e59b89c390d/skills/pdf", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/pdf", + "tree_sha": "6369f4649de69bd6857c9bc3b058a77206009238", + "skill_md_sha256": "9f78b8359fbd4943ad260a7a1e436e5a96503406d6c34e99f69223d647d85b9c", + "skill_md_bytes": 8072, + "description_chars": 437, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Handles document or research-report artifacts through the format-specific upstream workflow. Source: anthropics/skills@33375500bcea98d610eb30ce10ac4e59b89c390d skills/pdf/SKILL.md:1" + }, + { + "name": "pdflatex", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/pdflatex", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/pdflatex", + "tree_sha": "67c755b61c4ae488a59a98d34a160305fd2bb747", + "skill_md_sha256": "cf92e9e088dffea0c4849d85fa1d50697e1285f77896a3b03eec026ce61ff889", + "skill_md_bytes": 1278, + "description_chars": 166, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Handles document or research-report artifacts through the format-specific upstream workflow. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/pdflatex/SKILL.md:1" + }, + { + "name": "plain-english-content", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/plain-english-content", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/plain-english-content", + "tree_sha": "67903279d5ec4d43eb69f16fcbc964a3bde22862", + "skill_md_sha256": "2ef939ec154a2555a1018233ab818a4b0c92b16668c747b1ad9886a567c04ca2", + "skill_md_bytes": 6023, + "description_chars": 330, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides verifiable citations or reader-oriented documentation procedures for worker outputs. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/plain-english-content/SKILL.md:1" + }, + { + "name": "playwright", + "source": "openai/skills", + "url": "https://github.com/openai/skills/tree/49f948faa9258a0c61caceaf225e179651397431/skills/.curated/playwright", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "path": "skills/.curated/playwright", + "tree_sha": "74888f3c1d5581aea6415e78d5fbd760a8ab2a41", + "skill_md_sha256": "0ffaabcc8e0990627c4725f18bf1c7955534a796c1c199e872909de2013ce6a8", + "skill_md_bytes": 3771, + "description_chars": 209, + "upstream_disable_model_invocation": false, + "scenarios": [ + "e2e-testing" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Exercises browser-visible behavior and retains observable QA artifacts for applications and extraction callers. Source: openai/skills@49f948faa9258a0c61caceaf225e179651397431 skills/.curated/playwright/SKILL.md:1" + }, + { + "name": "pptx", + "source": "anthropics/skills", + "url": "https://github.com/anthropics/skills/tree/33375500bcea98d610eb30ce10ac4e59b89c390d/skills/pptx", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/pptx", + "tree_sha": "64529c8b3f35fe632b7256bd2f6d46e4b40160ce", + "skill_md_sha256": "a7ff03e2c85b636f55232a6b1555f5dd90216b7a1a359ab289d8364e6acbc6a0", + "skill_md_bytes": 20796, + "description_chars": 732, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Handles document or research-report artifacts through the format-specific upstream workflow. Source: anthropics/skills@33375500bcea98d610eb30ce10ac4e59b89c390d skills/pptx/SKILL.md:1" + }, + { + "name": "prd", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/prd", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/prd", + "tree_sha": "d009702520f9617ffea98984b75f176a7d9535e9", + "skill_md_sha256": "5de2431f9ceb205f76978940b7c1c65e503bb9603410088b8af75bdf2749eb61", + "skill_md_bytes": 6897, + "description_chars": 149, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Turns requirements into bounded designs or specifications before implementation. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/prd/SKILL.md:1" + }, + { + "name": "property-based-testing", + "source": "trailofbits/skills", + "url": "https://github.com/trailofbits/skills/tree/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/property-based-testing/skills/property-based-testing", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "path": "plugins/property-based-testing/skills/property-based-testing", + "tree_sha": "cf5e77d684180c80a2f3aa228c53d04b1fa1ba77", + "skill_md_sha256": "9448cacb65c6237a7c22dc59602667177ecae405524079ae9ff92240590b995a", + "skill_md_bytes": 4306, + "description_chars": 845, + "upstream_disable_model_invocation": false, + "scenarios": [ + "tdd", + "ab-testing-and-evaluation" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Covers whole parser and numeric input domains with shrinking rather than selected examples alone. Source: trailofbits/skills@0cc1c73a5e96749ab32d7ea5e14892fafa6972ae plugins/property-based-testing/skills/property-based-testing/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "qa-changes", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/qa-changes", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/qa-changes", + "tree_sha": "350f5d613a6d9d05ab6a4fc0adfaf9a62249e21e", + "skill_md_sha256": "e4819ced02fce8f19436d2314eb8426e4b4d2519cefa41c000908b53c45ff971", + "skill_md_bytes": 14712, + "description_chars": 325, + "upstream_disable_model_invocation": false, + "scenarios": [ + "e2e-testing" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Exercises browser-visible behavior and retains observable QA artifacts for applications and extraction callers. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/qa-changes/SKILL.md:1" + }, + { + "name": "receiving-code-review", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/receiving-code-review", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/receiving-code-review", + "tree_sha": "b5e154fc3ec7a6a0b1e710eebacc2168620cc428", + "skill_md_sha256": "091df1629510af1b92fc4abd6f96732ebedb4cb2c0f3457e8f2740b0504a2438", + "skill_md_bytes": 6203, + "description_chars": 234, + "upstream_disable_model_invocation": false, + "scenarios": [ + "code-review", + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides evidence-grounded change review and feedback handling as explicit lifecycle stages. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/receiving-code-review/SKILL.md:1" + }, + { + "name": "release-notes", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/release-notes", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/release-notes", + "tree_sha": "1494e93e3459d395907a4c00b815f93858bca20b", + "skill_md_sha256": "5250f2d1aa52272a91f0b0469f6b52079d4931b8bf32784b559706c87b8aeffb", + "skill_md_bytes": 854, + "description_chars": 191, + "upstream_disable_model_invocation": false, + "scenarios": [ + "release-notes", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Derives categorized release notes from repository history rather than model recollection. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/release-notes/SKILL.md:1" + }, + { + "name": "requesting-code-review", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/requesting-code-review", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/requesting-code-review", + "tree_sha": "5fcdadfccd8c90987a11969d2f8c844820fee6e1", + "skill_md_sha256": "cfcee1b06774e7c0517f1e09be1a11f2d5680257072723e709ddbcf7e08b795a", + "skill_md_bytes": 2977, + "description_chars": 107, + "upstream_disable_model_invocation": false, + "scenarios": [ + "code-review", + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides evidence-grounded change review and feedback handling as explicit lifecycle stages. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/requesting-code-review/SKILL.md:1" + }, + { + "name": "research", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/engineering/research", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/research", + "tree_sha": "0a6796c5667e95ed2301ba7381c123b4acb2ae1a", + "skill_md_sha256": "985569f15739c713d6784887c3d186d4ef9ac85bec5ad9c068d25bf0739928e4", + "skill_md_bytes": 794, + "description_chars": 238, + "upstream_disable_model_invocation": false, + "scenarios": [ + "research", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Collects high-trust primary-source findings into a cited repository artifact for coding decisions and research tasks. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/engineering/research/SKILL.md:1" + }, + { + "name": "research-brief", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/research-brief", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/research-brief", + "tree_sha": "96203abcbcdf42313e48380d51b5785e8d2a823b", + "skill_md_sha256": "662a6bf42ec9964bfe9d7f996ffe0fb388fec3e7c955df473d4bd729cd8309e6", + "skill_md_bytes": 3186, + "description_chars": 195, + "upstream_disable_model_invocation": false, + "scenarios": [ + "research", + "docs-and-citations" + ], + "roles": [ + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Defines recurring source-led research briefs with verifiable sources; Tavily/Notion integrations require native setup and publishing authority. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/research-brief/SKILL.md:1" + }, + { + "name": "resolving-merge-conflicts", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/engineering/resolving-merge-conflicts", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/resolving-merge-conflicts", + "tree_sha": "77f0d7de3143abbf03e55a63522d30bff31ae908", + "skill_md_sha256": "9d8114f8ef0b31f535a265fc05c364bd8cf2e2895a830040e06c22acb11f54b0", + "skill_md_bytes": 918, + "description_chars": 70, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-issue-to-pr", + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers source-control state, conflicts and integration steps through native git/GitHub operations. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/engineering/resolving-merge-conflicts/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "sarif-parsing", + "source": "trailofbits/skills", + "url": "https://github.com/trailofbits/skills/tree/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/static-analysis/skills/sarif-parsing", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "path": "plugins/static-analysis/skills/sarif-parsing", + "tree_sha": "4fe407da56e118c68fd9bcc16603a38cf6116562", + "skill_md_sha256": "cc5f008f40ffb8a1ae03ebd32d7234de43e828293955a0bc251b76ba249554fa", + "skill_md_bytes": 17925, + "description_chars": 373, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies maintained security scanning or finding triage with explicit evidence and false-positive handling. Source: trailofbits/skills@0cc1c73a5e96749ab32d7ea5e14892fafa6972ae plugins/static-analysis/skills/sarif-parsing/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "score-quality", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/migration-scoring/skills/score-quality", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/migration-scoring/skills/score-quality", + "tree_sha": "15e66548eca0b7a0fc52d2f6ba528b9cd028d525", + "skill_md_sha256": "c0a0955e32eff9c6671b9d2d68eae9d55134d78c5193bd3fda506b50e020fd8a", + "skill_md_bytes": 1512, + "description_chars": 127, + "upstream_disable_model_invocation": false, + "scenarios": [ + "ab-testing-and-evaluation", + "code-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Adds rubric-driven migration evaluation and reports; plugin hooks are not installed by the skills CLI. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/migration-scoring/skills/score-quality/SKILL.md:1" + }, + { + "name": "score-style", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/migration-scoring/skills/score-style", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/migration-scoring/skills/score-style", + "tree_sha": "5ea273ae511d5fc02eedeb0afe55c11c0712d65a", + "skill_md_sha256": "7c461adc030dda47100f26f8acea6c3098975789c7646b17eec8549985f30702", + "skill_md_bytes": 2885, + "description_chars": 126, + "upstream_disable_model_invocation": false, + "scenarios": [ + "ab-testing-and-evaluation", + "code-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Adds rubric-driven migration evaluation and reports; plugin hooks are not installed by the skills CLI. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/migration-scoring/skills/score-style/SKILL.md:1" + }, + { + "name": "search-first", + "source": "affaan-m/ECC", + "url": "https://github.com/affaan-m/ECC/tree/2b6e839771e53096d8451a213d40dc64ec8acac0/skills/search-first", + "ref": "2b6e839771e53096d8451a213d40dc64ec8acac0", + "path": "skills/search-first", + "tree_sha": "89e0ce14188958a85fbfc7ae0bdc30a0dc9681e1", + "skill_md_sha256": "d66d744228b9cf860acf35f8a90cbbe8195e61367860da9d3632f9fc65706733", + "skill_md_bytes": 8021, + "description_chars": 141, + "upstream_disable_model_invocation": false, + "scenarios": [ + "research", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Compares existing repositories, packages and skills before writing integration code, directly supporting coding and orchestration work. Source: affaan-m/ECC@2b6e839771e53096d8451a213d40dc64ec8acac0 skills/search-first/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "security", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/security", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/security", + "tree_sha": "17f0062e8f675bce2b5c4d3d6ffb30a6e94017d6", + "skill_md_sha256": "887a8c46466e388665d4b6679a6d1fe02c6a79b527c38aed6a5a6291b6831fa3", + "skill_md_bytes": 1367, + "description_chars": 200, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Adds secure design and trust-boundary review for runtime tools and untrusted extracted inputs. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/security/SKILL.md:1" + }, + { + "name": "security-best-practices", + "source": "openai/skills", + "url": "https://github.com/openai/skills/tree/49f948faa9258a0c61caceaf225e179651397431/skills/.curated/security-best-practices", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "path": "skills/.curated/security-best-practices", + "tree_sha": "349d45885fd3e432e7d0e5c6e21a2a712db158ef", + "skill_md_sha256": "7b3dae1ffc5434d890f3c65c8f552af52d0307fab3b35dec13013c9ca3844c4f", + "skill_md_bytes": 8612, + "description_chars": 385, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Adds secure design and trust-boundary review for runtime tools and untrusted extracted inputs. Source: openai/skills@49f948faa9258a0c61caceaf225e179651397431 skills/.curated/security-best-practices/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "security-threat-model", + "source": "openai/skills", + "url": "https://github.com/openai/skills/tree/49f948faa9258a0c61caceaf225e179651397431/skills/.curated/security-threat-model", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "path": "skills/.curated/security-threat-model", + "tree_sha": "455ed2d898ef7d1e8836898f07be3a7d2c3f38d2", + "skill_md_sha256": "1283c0dd62a8104d9edda4583569b5d8510b4ddaa45120687c999250fd96bad2", + "skill_md_bytes": 5561, + "description_chars": 412, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Adds secure design and trust-boundary review for runtime tools and untrusted extracted inputs. Source: openai/skills@49f948faa9258a0c61caceaf225e179651397431 skills/.curated/security-threat-model/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "semgrep", + "source": "trailofbits/skills", + "url": "https://github.com/trailofbits/skills/tree/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/static-analysis/skills/semgrep", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "path": "plugins/static-analysis/skills/semgrep", + "tree_sha": "7503c4bec67cbe758ee488a2bd4caaf618facbfb", + "skill_md_sha256": "04df36a7685632ee39271aa432a4d32e1203b326e4a8091e6f5c0eb191ef90f1", + "skill_md_bytes": 15531, + "description_chars": 707, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies maintained security scanning or finding triage with explicit evidence and false-positive handling. Source: trailofbits/skills@0cc1c73a5e96749ab32d7ea5e14892fafa6972ae plugins/static-analysis/skills/semgrep/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "setup-agents-md", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/onboarding/skills/setup-agents-md", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/onboarding/skills/setup-agents-md", + "tree_sha": "4699322855418d8df34d0c8e0d61042d267ff026", + "skill_md_sha256": "33abece9c9e2726377e39d4adb0569ed46c6336e8bfc41e290462940e008a613", + "skill_md_bytes": 6035, + "description_chars": 369, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Checks and improves repository instructions and feedback loops for autonomous workers. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/onboarding/skills/setup-agents-md/SKILL.md:1" + }, + { + "name": "setup-openhands", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/onboarding/skills/setup-openhands", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/onboarding/skills/setup-openhands", + "tree_sha": "160dd94a55fb88d883a3f7b576378a0140e26a7a", + "skill_md_sha256": "1c2381e0c1547d3c5efe675f3ae0a6e863fefb5e6867178162772770522f9629", + "skill_md_bytes": 2222, + "description_chars": 251, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-actions" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies native workflow setup and debugging procedures instead of generated CI guesses. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/onboarding/skills/setup-openhands/SKILL.md:1" + }, + { + "name": "setup-pr-review", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/onboarding/skills/setup-pr-review", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/onboarding/skills/setup-pr-review", + "tree_sha": "fa20714069063b154a9afc08c21bbb6acbc2817c", + "skill_md_sha256": "70b8d5fb44619412ff7b9bc7794a94ab4a6ab9f14198218c85739463026b1513", + "skill_md_bytes": 2939, + "description_chars": 209, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides review dispatch or review API procedures; installation grants no permission to post or merge. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/onboarding/skills/setup-pr-review/SKILL.md:1" + }, + { + "name": "skill-creator", + "source": "anthropics/skills", + "url": "https://github.com/anthropics/skills/tree/33375500bcea98d610eb30ce10ac4e59b89c390d/skills/skill-creator", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/skill-creator", + "tree_sha": "3cf9a8db32597ba3e24b584a3d696f4e11c7d7b6", + "skill_md_sha256": "dcd4803e61e913e6fc27294184cd3a71f09f5e924ff20c8a9a20173e7b3c2bcf", + "skill_md_bytes": 33168, + "description_chars": 319, + "upstream_disable_model_invocation": false, + "scenarios": [ + "ab-testing-and-evaluation" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Includes baseline runs, grader rubrics, repeated benchmarks and blind A/B comparison for skill quality; this does not cover product traffic experiments. Source: anthropics/skills@33375500bcea98d610eb30ce10ac4e59b89c390d skills/skill-creator/SKILL.md:1" + }, + { + "name": "slack-channel-monitor", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/slack-channel-monitor", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/slack-channel-monitor", + "tree_sha": "d3dfabd9f8790f45e6a15274510050817dd6d0da", + "skill_md_sha256": "2699798becdf629b7a837bca297c91fe26fa486fdf2a3a80ca628c56463f3f40", + "skill_md_bytes": 12730, + "description_chars": 481, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations", + "memory" + ], + "roles": [ + "orchestration", + "research" + ], + "status": "trial", + "merit_note": "Structures authorized team context, incident evidence or knowledge records; external messages require session authority. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/slack-channel-monitor/SKILL.md:1" + }, + { + "name": "slack-standup-digest", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/slack-standup-digest", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/slack-standup-digest", + "tree_sha": "9e7ff432df4f3610aaf5628503b8e69122fe119e", + "skill_md_sha256": "58e779cdde7f0029d31df290f0d3a93600fa902ba077393b392a51cbd7e5e699", + "skill_md_bytes": 3208, + "description_chars": 242, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations", + "memory" + ], + "roles": [ + "orchestration", + "research" + ], + "status": "trial", + "merit_note": "Structures authorized team context, incident evidence or knowledge records; external messages require session authority. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/slack-standup-digest/SKILL.md:1" + }, + { + "name": "spark-version-upgrade", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/spark-version-upgrade", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/spark-version-upgrade", + "tree_sha": "1fade147a86861825148668e9157b8078a45b32b", + "skill_md_sha256": "4351d37aec3b7b19cc52bba87aaa8c48c67c0ee4a50e73afcb175aeca4fe4762", + "skill_md_bytes": 7777, + "description_chars": 180, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "tdd" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers specialized language migrations with test fixtures and explicit transformation steps. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/spark-version-upgrade/SKILL.md:1" + }, + { + "name": "ssh", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/ssh", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/ssh", + "tree_sha": "3faad5282472c8b5ccb6ecdef8ef3c5e0f64251d", + "skill_md_sha256": "ca7cca10ed32ca284afafecff35fa3218aa9baee1ed62ab415393adfe9817324", + "skill_md_bytes": 3371, + "description_chars": 214, + "upstream_disable_model_invocation": false, + "scenarios": [ + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides native environment, package or deployment procedures; actual deployment credentials and runtime acceptance remain separate. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/ssh/SKILL.md:1" + }, + { + "name": "subagent-driven-development", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/subagent-driven-development", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/subagent-driven-development", + "tree_sha": "5d44ced88725298e847c62c67a726dcc29e20d00", + "skill_md_sha256": "8dde5589ee083fb4999106d116f01c8fdaf3116a8a9813fdedeb80329de49046", + "skill_md_bytes": 32577, + "description_chars": 85, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies an execution, isolation or delegation step in the development lifecycle; native worker tool availability remains a gate. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/subagent-driven-development/SKILL.md:1" + }, + { + "name": "supply-chain-risk-auditor", + "source": "trailofbits/skills", + "url": "https://github.com/trailofbits/skills/tree/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/supply-chain-risk-auditor/skills/supply-chain-risk-auditor", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "path": "plugins/supply-chain-risk-auditor/skills/supply-chain-risk-auditor", + "tree_sha": "954cc68e05e24a2a14447b60d1e8946b53323b1b", + "skill_md_sha256": "a1254b7f8d3a1731a9a7e1f9cd6c67b59cf84ed6ef7c7fb455db9a14c528ceb4", + "skill_md_bytes": 6991, + "description_chars": 367, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies maintained security scanning or finding triage with explicit evidence and false-positive handling. Source: trailofbits/skills@0cc1c73a5e96749ab32d7ea5e14892fafa6972ae plugins/supply-chain-risk-auditor/skills/supply-chain-risk-auditor/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "swift-linux", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/swift-linux", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/swift-linux", + "tree_sha": "60790b9ebdbbf4794cc5614e999f08b8b90bce88", + "skill_md_sha256": "e4c39d4cfd04335df7e6d6d799470143ac7e805d7a98ca9366f2867a65c80ccc", + "skill_md_bytes": 2637, + "description_chars": 186, + "upstream_disable_model_invocation": false, + "scenarios": [ + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides native environment, package or deployment procedures; actual deployment credentials and runtime acceptance remain separate. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/swift-linux/SKILL.md:1" + }, + { + "name": "systematic-debugging", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/systematic-debugging", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/systematic-debugging", + "tree_sha": "9a48dfda84bf339cba4b03fd803ba0dca2e158e3", + "skill_md_sha256": "808fc5717aa88ad65efff312b11c186294d3e6ee301afb584e2f86599b137787", + "skill_md_bytes": 9465, + "description_chars": 91, + "upstream_disable_model_invocation": false, + "scenarios": [ + "debugging" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Uses hypothesis-driven diagnosis and root-cause evidence before proposing fixes. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/systematic-debugging/SKILL.md:1" + }, + { + "name": "tdd", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/engineering/tdd", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/tdd", + "tree_sha": "79288be15c67b849f22b6572056601090fd20913", + "skill_md_sha256": "cb01f66bebfaa25fa1f88e6b7e769cd9fd9f35b1120b8563749820738814c927", + "skill_md_bytes": 3549, + "description_chars": 149, + "upstream_disable_model_invocation": false, + "scenarios": [ + "tdd" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Defines a red/green loop and behavior-level tests; callers can test deterministic extraction contracts. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/engineering/tdd/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "technical-writing", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/technical-writing", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/technical-writing", + "tree_sha": "c3d06b8ed68fbdff5c19d8e03ffba2de2530b081", + "skill_md_sha256": "ddd627776d70161f3296dbbbb79c9592a9d89e4eab0622b9217eed648dae7b05", + "skill_md_bytes": 4888, + "description_chars": 282, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides verifiable citations or reader-oriented documentation procedures for worker outputs. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/technical-writing/SKILL.md:1" + }, + { + "name": "test-driven-development", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/test-driven-development", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/test-driven-development", + "tree_sha": "847144cf0824095922c0d4875648b9fa74877e1a", + "skill_md_sha256": "64b03fce4aee5a97a93160cea8111f3ba13a17b7c001db4bd5836d67fd10705d", + "skill_md_bytes": 9578, + "description_chars": 79, + "upstream_disable_model_invocation": false, + "scenarios": [ + "tdd" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Defines a red/green loop and behavior-level tests; callers can test deterministic extraction contracts. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/test-driven-development/SKILL.md:1" + }, + { + "name": "theme-factory", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/theme-factory", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/theme-factory", + "tree_sha": "8942a4f915c681dbc62047d4bfa11f998738ecb0", + "skill_md_sha256": "c35893e221e28895c52143cc11bf30e41a44817796b39d4b15727dadc9796552", + "skill_md_bytes": 3124, + "description_chars": 262, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Handles document or research-report artifacts through the format-specific upstream workflow. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/theme-factory/SKILL.md:1" + }, + { + "name": "ticket-to-code-change", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/ticket-to-code-change", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/ticket-to-code-change", + "tree_sha": "062c50c64ebe0b86de3adda752208dd8b3539d49", + "skill_md_sha256": "1d063f120e1238dadea3b1a59531373e249b815b772e1970e99fa0fea3cffcc2", + "skill_md_bytes": 2278, + "description_chars": 330, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-issue-to-pr" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Provides issue intake, implementation or dispatch procedures tied to observable repository state. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/ticket-to-code-change/SKILL.md:1" + }, + { + "name": "to-java-migration", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/cobol-modernization/skills/to-java-migration", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/cobol-modernization/skills/to-java-migration", + "tree_sha": "e5bc7457ba29e05f0abdedb957f6121dd15e795e", + "skill_md_sha256": "59e8581f49351e9fa6e89ae76faa8a3c59bc014797f26cfa54769de4cd4c1970", + "skill_md_bytes": 2089, + "description_chars": 138, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "tdd" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers specialized language migrations with test fixtures and explicit transformation steps. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 plugins/cobol-modernization/skills/to-java-migration/SKILL.md:1" + }, + { + "name": "to-spec", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/engineering/to-spec", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/to-spec", + "tree_sha": "136b9651747cfccbfbb7c50a6b0dfb757e7547d2", + "skill_md_sha256": "43ad9cf318e5e7d3d1fa360253a37021796dc87a0c2e595ad262661a10f85088", + "skill_md_bytes": 3043, + "description_chars": 149, + "upstream_disable_model_invocation": true, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Turns requirements into bounded designs or specifications before implementation. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/engineering/to-spec/SKILL.md:1" + }, + { + "name": "to-tickets", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/engineering/to-tickets", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/to-tickets", + "tree_sha": "b32c94e5a51c24ee9c41fcb7fe9ea9fff9af6369", + "skill_md_sha256": "5c9fba69845c2519b9b35b9af42ae5142c21f8ca15ac2123dc2722002c8058ae", + "skill_md_bytes": 5671, + "description_chars": 247, + "upstream_disable_model_invocation": true, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies an execution, isolation or delegation step in the development lifecycle; native worker tool availability remains a gate. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/engineering/to-tickets/SKILL.md:1" + }, + { + "name": "typesafe-ai", + "source": "typesafe-ai/skills", + "url": "https://github.com/typesafe-ai/skills/tree/65a39f393687675ce170e6094757de20370365b9/skills/typesafe-ai", + "ref": "65a39f393687675ce170e6094757de20370365b9", + "path": "skills/typesafe-ai", + "tree_sha": "678c375b883794bf4292715a43acbba5c84681aa", + "skill_md_sha256": "71ea90d7906c6554c4f4c460ef7361b2d26f59116ccdae986dc6d997b9389f52", + "skill_md_bytes": 10040, + "description_chars": 660, + "upstream_disable_model_invocation": false, + "scenarios": [ + "ab-testing-and-evaluation" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides typed judgments for routing and verification; trial requires task-specific quality evaluation. Source: typesafe-ai/skills@65a39f393687675ce170e6094757de20370365b9 skills/typesafe-ai/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "upstream-fork-sync", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/upstream-fork-sync", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/upstream-fork-sync", + "tree_sha": "2dbfcf26ede4df1236f2d5882defc39b639d2574", + "skill_md_sha256": "c53faa66ce41f0846116b4463313e4a985024eccd6e6ec6d0603a869aee0186d", + "skill_md_bytes": 4606, + "description_chars": 388, + "upstream_disable_model_invocation": false, + "scenarios": [ + "github-issue-to-pr", + "github-pr-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Covers source-control state, conflicts and integration steps through native git/GitHub operations. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/upstream-fork-sync/SKILL.md:1" + }, + { + "name": "using-git-worktrees", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/using-git-worktrees", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/using-git-worktrees", + "tree_sha": "d2b8357b922667a091bfe967840abf5ae84ce99c", + "skill_md_sha256": "8cfb86f121269e8f7f12361e6795c4f6738828340e28964c9229d365666c9edd", + "skill_md_bytes": 6813, + "description_chars": 196, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies an execution, isolation or delegation step in the development lifecycle; native worker tool availability remains a gate. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/using-git-worktrees/SKILL.md:1" + }, + { + "name": "using-superpowers", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/using-superpowers", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/using-superpowers", + "tree_sha": "4c777432715fe58984d212a36aedc6a18472e512", + "skill_md_sha256": "82c5c8866ad7f5dd4440ce66bd7806ba48a2f13771beae5cf112e53f08fe36ba", + "skill_md_bytes": 3192, + "description_chars": 154, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies an execution, isolation or delegation step in the development lifecycle; native worker tool availability remains a gate. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/using-superpowers/SKILL.md:1" + }, + { + "name": "uv", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/uv", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/uv", + "tree_sha": "35be5b0352ad8f5cba3b92b3fbb6162b260e9a24", + "skill_md_sha256": "e321822ec05752b5fd8b967f6bec30f0e9fd5d7d042aaf5a5d7002829d788315", + "skill_md_bytes": 2639, + "description_chars": 216, + "upstream_disable_model_invocation": false, + "scenarios": [ + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides native environment, package or deployment procedures; actual deployment credentials and runtime acceptance remain separate. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/uv/SKILL.md:1" + }, + { + "name": "variant-analysis", + "source": "trailofbits/skills", + "url": "https://github.com/trailofbits/skills/tree/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/variant-analysis/skills/variant-analysis", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "path": "plugins/variant-analysis/skills/variant-analysis", + "tree_sha": "583d7addbf5e04108cc5fece9c99a4d9c6db5ce9", + "skill_md_sha256": "7b6b78e499bcb88d05c68254ffc91ebc28edabf4e9808adcc40e2628ebb9407e", + "skill_md_bytes": 3903, + "description_chars": 566, + "upstream_disable_model_invocation": false, + "scenarios": [ + "security" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies maintained security scanning or finding triage with explicit evidence and false-positive handling. Source: trailofbits/skills@0cc1c73a5e96749ab32d7ea5e14892fafa6972ae plugins/variant-analysis/skills/variant-analysis/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "vercel", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/vercel", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/vercel", + "tree_sha": "a1a03f2db71aea8b1a1f8cedea6cfd57963de76b", + "skill_md_sha256": "4060634017206b72caca6ad05195cd015a5309569d336cbc5b04dab263769b12", + "skill_md_bytes": 3240, + "description_chars": 178, + "upstream_disable_model_invocation": false, + "scenarios": [ + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Provides native environment, package or deployment procedures; actual deployment credentials and runtime acceptance remain separate. Source: OpenHands/extensions@bea7a20c59c44ec4dacddac3fc0efe58b9c73880 skills/vercel/SKILL.md:1" + }, + { + "name": "vercel-composition-patterns", + "source": "vercel-labs/agent-skills", + "url": "https://github.com/vercel-labs/agent-skills/tree/063bee94c3f4df8453406c830b0a7df0f2860278/skills/composition-patterns", + "ref": "063bee94c3f4df8453406c830b0a7df0f2860278", + "path": "skills/composition-patterns", + "tree_sha": "bf90d0a4b83ea054653350f9c67f6de235d3a368", + "skill_md_sha256": "e38e0eaa609316b10423a9a138ed95e35099accd3f735585295c8a8f165c28a3", + "skill_md_bytes": 2886, + "description_chars": 310, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs", + "code-review" + ], + "roles": [ + "coding" + ], + "status": "trial", + "merit_note": "Adds intentional UI design or reusable component-interface criteria to coding work. Source: vercel-labs/agent-skills@063bee94c3f4df8453406c830b0a7df0f2860278 skills/composition-patterns/SKILL.md:1" + }, + { + "name": "vercel-optimize", + "source": "vercel-labs/agent-skills", + "url": "https://github.com/vercel-labs/agent-skills/tree/063bee94c3f4df8453406c830b0a7df0f2860278/skills/vercel-optimize", + "ref": "063bee94c3f4df8453406c830b0a7df0f2860278", + "path": "skills/vercel-optimize", + "tree_sha": "0901aa3667db7a6e5cc40b213327290bf6556373", + "skill_md_sha256": "95ae2683b30d892d165af92a350c5628b68106f395a59b448857b654e306ed91", + "skill_md_bytes": 17311, + "description_chars": 566, + "upstream_disable_model_invocation": false, + "scenarios": [ + "ab-testing-and-evaluation", + "deployment-uv-docker" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Grounds deployment optimization in observed performance and cost measurements. Source: vercel-labs/agent-skills@063bee94c3f4df8453406c830b0a7df0f2860278 skills/vercel-optimize/SKILL.md:1" + }, + { + "name": "vercel-react-best-practices", + "source": "vercel-labs/agent-skills", + "url": "https://github.com/vercel-labs/agent-skills/tree/063bee94c3f4df8453406c830b0a7df0f2860278/skills/react-best-practices", + "ref": "063bee94c3f4df8453406c830b0a7df0f2860278", + "path": "skills/react-best-practices", + "tree_sha": "343db72180d05814949fef7d46be96b5c6ee86b3", + "skill_md_sha256": "71ed7794962fa6e803ee83030517b5b93a9f70fbfeb431ec4535c5480a8d8355", + "skill_md_bytes": 7251, + "description_chars": 329, + "upstream_disable_model_invocation": false, + "scenarios": [ + "code-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Adds framework-specific performance or accessibility criteria to review. Source: vercel-labs/agent-skills@063bee94c3f4df8453406c830b0a7df0f2860278 skills/react-best-practices/SKILL.md:1" + }, + { + "name": "web-design-guidelines", + "source": "vercel-labs/agent-skills", + "url": "https://github.com/vercel-labs/agent-skills/tree/063bee94c3f4df8453406c830b0a7df0f2860278/skills/web-design-guidelines", + "ref": "063bee94c3f4df8453406c830b0a7df0f2860278", + "path": "skills/web-design-guidelines", + "tree_sha": "3116f3e62dbd02b44a598b1aa690d2a8938e8f89", + "skill_md_sha256": "f4647ca866a3accf763777f83e7682954f0187cd6bea7eea0399796652414e8f", + "skill_md_bytes": 1231, + "description_chars": 184, + "upstream_disable_model_invocation": false, + "scenarios": [ + "code-review" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Adds framework-specific performance or accessibility criteria to review. Source: vercel-labs/agent-skills@063bee94c3f4df8453406c830b0a7df0f2860278 skills/web-design-guidelines/SKILL.md:1" + }, + { + "name": "webapp-testing", + "source": "anthropics/skills", + "url": "https://github.com/anthropics/skills/tree/33375500bcea98d610eb30ce10ac4e59b89c390d/skills/webapp-testing", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/webapp-testing", + "tree_sha": "5ffb7dc66b9fd4c25c3e400a4c00da99a349b714", + "skill_md_sha256": "51b7349e77ec63b7744a6f63647e7566a0b4d2e301121cc10e8c2113af6556a2", + "skill_md_bytes": 3913, + "description_chars": 204, + "upstream_disable_model_invocation": false, + "scenarios": [ + "e2e-testing" + ], + "roles": [ + "coding", + "orchestration", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Exercises browser-visible behavior and retains observable QA artifacts for applications and extraction callers. Source: anthropics/skills@33375500bcea98d610eb30ce10ac4e59b89c390d skills/webapp-testing/SKILL.md:1" + }, + { + "name": "writing-for-agents", + "source": "mattpocock/skills", + "url": "https://github.com/mattpocock/skills/tree/c55ee46073ed923f86ce59a5eb3b6d895095d1b7/skills/productivity/writing-for-agents", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/productivity/writing-for-agents", + "tree_sha": "ad2925850efb8973a72d2e666f7a975f9a2d4a9b", + "skill_md_sha256": "551adca942227b44192edba88acd4e8db911f0121ce58ad16944ccf6a896a74a", + "skill_md_bytes": 10886, + "description_chars": 103, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations", + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration" + ], + "status": "trial", + "merit_note": "Supplies domain-specific documentation or integration design guidance backed by the upstream implementation. Source: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7 skills/productivity/writing-for-agents/SKILL.md:1", + "reuse_ref": "adoption/skills/manifest.json" + }, + { + "name": "writing-plans", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/writing-plans", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/writing-plans", + "tree_sha": "cc97fa00eb2ccd4f283e34eb2ba06a48e1e679f7", + "skill_md_sha256": "a6c67c1900064347c2a329990dd3c555657c51c3ec53b259a08aa01a2c26139a", + "skill_md_bytes": 10335, + "description_chars": 84, + "upstream_disable_model_invocation": false, + "scenarios": [ + "planning-and-specs" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Turns requirements into bounded designs or specifications before implementation. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/writing-plans/SKILL.md:1" + }, + { + "name": "writing-skills", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/writing-skills", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/writing-skills", + "tree_sha": "f761162236b19330da62b22ad0da20f5dac7c6ab", + "skill_md_sha256": "bbdfe742f853562e643a3d40d64476359d47881e39cef80a189283fa26d11ab9", + "skill_md_bytes": 26623, + "description_chars": 97, + "upstream_disable_model_invocation": false, + "scenarios": [ + "ab-testing-and-evaluation", + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Uses test scenarios to exercise skill instructions and their triggering behavior before publication. Source: obra/superpowers@8ca22dba9a94f28898bbce59f2537ff4d87c747d skills/writing-skills/SKILL.md:1" + }, + { + "name": "xlsx", + "source": "anthropics/skills", + "url": "https://github.com/anthropics/skills/tree/33375500bcea98d610eb30ce10ac4e59b89c390d/skills/xlsx", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/xlsx", + "tree_sha": "fe6471cc9b5b97aae0b576ccb92ffd9b0207589d", + "skill_md_sha256": "6712b39718fe815054abca9c3ee72f989613e6f771c8a5c58f30a65a6c905622", + "skill_md_bytes": 8598, + "description_chars": 948, + "upstream_disable_model_invocation": false, + "scenarios": [ + "docs-and-citations" + ], + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "status": "trial", + "merit_note": "Handles document or research-report artifacts through the format-specific upstream workflow. Source: anthropics/skills@33375500bcea98d610eb30ce10ac4e59b89c390d skills/xlsx/SKILL.md:1" + } + ], + "coverage": { + "planning-and-specs": { + "coding": [ + "add-javadoc", + "agent-canvas-environment", + "agent-creator", + "agent-readiness-report", + "agent-sdk-builder", + "azure-devops", + "bitbucket", + "bitbucket-cloud", + "bitbucket-data-center", + "brainstorming", + "build-setup", + "canvas-extension-api", + "cobol-modernization", + "codebase-design", + "dispatching-parallel-agents", + "domain-modeling", + "executing-plans", + "frontend-design", + "gitlab", + "gitlab-issue-to-mr", + "grill-me", + "improve-agent-readiness", + "improve-codebase-architecture", + "linear", + "linear-triage", + "mainframe-planning", + "mainframe-removal", + "mcp-builder", + "openhands-api", + "openhands-automation", + "openhands-sdk", + "prd", + "setup-agents-md", + "spark-version-upgrade", + "subagent-driven-development", + "to-java-migration", + "to-spec", + "to-tickets", + "using-git-worktrees", + "using-superpowers", + "vercel-composition-patterns", + "writing-for-agents", + "writing-plans" + ], + "orchestration": [ + "add-javadoc", + "agent-canvas-environment", + "agent-creator", + "agent-readiness-report", + "agent-sdk-builder", + "azure-devops", + "bitbucket", + "bitbucket-cloud", + "bitbucket-data-center", + "brainstorming", + "build-setup", + "canvas-extension-api", + "cobol-modernization", + "codebase-design", + "dispatching-parallel-agents", + "domain-modeling", + "executing-plans", + "gitlab", + "gitlab-issue-to-mr", + "grill-me", + "improve-agent-readiness", + "improve-codebase-architecture", + "linear", + "linear-triage", + "mainframe-planning", + "mainframe-removal", + "mcp-builder", + "openhands-api", + "openhands-automation", + "openhands-sdk", + "prd", + "setup-agents-md", + "spark-version-upgrade", + "subagent-driven-development", + "to-java-migration", + "to-spec", + "to-tickets", + "using-git-worktrees", + "using-superpowers", + "writing-for-agents", + "writing-plans" + ], + "research": [ + "brainstorming", + "domain-modeling", + "grill-me", + "prd", + "to-spec", + "writing-plans" + ], + "extraction-caller": [ + "brainstorming", + "codebase-design", + "domain-modeling", + "grill-me", + "improve-codebase-architecture", + "prd", + "to-spec", + "writing-plans" + ] + }, + "tdd": { + "coding": [ + "build-setup", + "cobol-modernization", + "mainframe-planning", + "mainframe-removal", + "property-based-testing", + "spark-version-upgrade", + "tdd", + "test-driven-development", + "to-java-migration" + ], + "orchestration": [ + "build-setup", + "cobol-modernization", + "mainframe-planning", + "mainframe-removal", + "property-based-testing", + "spark-version-upgrade", + "tdd", + "test-driven-development", + "to-java-migration" + ], + "research": [], + "extraction-caller": [ + "property-based-testing", + "tdd", + "test-driven-development" + ] + }, + "e2e-testing": { + "coding": [ + "agent-browser", + "playwright", + "qa-changes", + "webapp-testing" + ], + "orchestration": [ + "agent-browser", + "playwright", + "qa-changes", + "webapp-testing" + ], + "research": [], + "extraction-caller": [ + "agent-browser", + "playwright", + "qa-changes", + "webapp-testing" + ] + }, + "ab-testing-and-evaluation": { + "coding": [ + "diagnosing-superpowers", + "jupyter", + "jupyter-notebook", + "migration-mapping", + "migration-report", + "migration-scoring", + "property-based-testing", + "score-quality", + "score-style", + "skill-creator", + "typesafe-ai", + "vercel-optimize", + "writing-skills" + ], + "orchestration": [ + "diagnosing-superpowers", + "migration-mapping", + "migration-report", + "migration-scoring", + "property-based-testing", + "score-quality", + "score-style", + "skill-creator", + "typesafe-ai", + "vercel-optimize", + "writing-skills" + ], + "research": [ + "jupyter", + "jupyter-notebook", + "skill-creator", + "writing-skills" + ], + "extraction-caller": [ + "jupyter", + "jupyter-notebook", + "property-based-testing", + "skill-creator", + "typesafe-ai", + "writing-skills" + ] + }, + "debugging": { + "coding": [ + "datadog", + "diagnosing-bugs", + "diagnosing-superpowers", + "openhands-enterprise-troubleshooting", + "systematic-debugging" + ], + "orchestration": [ + "datadog", + "diagnosing-bugs", + "diagnosing-superpowers", + "openhands-enterprise-troubleshooting", + "systematic-debugging" + ], + "research": [ + "diagnosing-bugs", + "systematic-debugging" + ], + "extraction-caller": [ + "diagnosing-bugs", + "systematic-debugging" + ] + }, + "code-review": { + "coding": [ + "code-review", + "code-simplifier", + "codebase-design", + "frontend-design", + "gh-address-comments", + "improve-codebase-architecture", + "migration-mapping", + "migration-report", + "migration-scoring", + "receiving-code-review", + "requesting-code-review", + "score-quality", + "score-style", + "vercel-composition-patterns", + "vercel-react-best-practices", + "web-design-guidelines" + ], + "orchestration": [ + "code-review", + "code-simplifier", + "codebase-design", + "gh-address-comments", + "improve-codebase-architecture", + "migration-mapping", + "migration-report", + "migration-scoring", + "receiving-code-review", + "requesting-code-review", + "score-quality", + "score-style", + "vercel-react-best-practices", + "web-design-guidelines" + ], + "research": [], + "extraction-caller": [ + "codebase-design", + "improve-codebase-architecture" + ] + }, + "security": { + "coding": [ + "agentic-actions-auditor", + "codeql", + "fp-check", + "sarif-parsing", + "security", + "security-best-practices", + "security-threat-model", + "semgrep", + "supply-chain-risk-auditor", + "variant-analysis" + ], + "orchestration": [ + "agentic-actions-auditor", + "codeql", + "fp-check", + "sarif-parsing", + "security", + "security-best-practices", + "security-threat-model", + "semgrep", + "supply-chain-risk-auditor", + "variant-analysis" + ], + "research": [], + "extraction-caller": [ + "security", + "security-best-practices", + "security-threat-model" + ] + }, + "github-issue-to-pr": { + "coding": [ + "finishing-a-development-branch", + "github", + "github-issue-to-pr", + "github-issue-triage", + "github-repo-monitor", + "jira-issue-to-pr", + "resolving-merge-conflicts", + "ticket-to-code-change", + "upstream-fork-sync" + ], + "orchestration": [ + "finishing-a-development-branch", + "github", + "github-issue-to-pr", + "github-issue-triage", + "github-repo-monitor", + "jira-issue-to-pr", + "resolving-merge-conflicts", + "ticket-to-code-change", + "upstream-fork-sync" + ], + "research": [], + "extraction-caller": [] + }, + "github-pr-review": { + "coding": [ + "code-review", + "code-simplifier", + "finishing-a-development-branch", + "gh-address-comments", + "github", + "github-delivery-watchdog", + "github-pr-review", + "github-pr-reviewer", + "receiving-code-review", + "requesting-code-review", + "resolving-merge-conflicts", + "setup-pr-review", + "upstream-fork-sync" + ], + "orchestration": [ + "code-review", + "code-simplifier", + "finishing-a-development-branch", + "gh-address-comments", + "github", + "github-delivery-watchdog", + "github-pr-review", + "github-pr-reviewer", + "receiving-code-review", + "requesting-code-review", + "resolving-merge-conflicts", + "setup-pr-review", + "upstream-fork-sync" + ], + "research": [], + "extraction-caller": [] + }, + "github-ci-fix": { + "coding": [ + "gh-fix-ci", + "github-stale-ci-pr-closer", + "iterate" + ], + "orchestration": [ + "gh-fix-ci", + "github-stale-ci-pr-closer", + "iterate" + ], + "research": [], + "extraction-caller": [] + }, + "github-actions": { + "coding": [ + "agentic-actions-auditor", + "github-actions", + "setup-openhands" + ], + "orchestration": [ + "agentic-actions-auditor", + "github-actions", + "setup-openhands" + ], + "research": [], + "extraction-caller": [] + }, + "release-notes": { + "coding": [ + "release-notes" + ], + "orchestration": [ + "release-notes" + ], + "research": [], + "extraction-caller": [] + }, + "docs-and-citations": { + "coding": [ + "add-javadoc", + "agent-memory", + "agent-readiness-report", + "doc-coauthoring", + "docx", + "evidence-based-citations", + "find-skills", + "github-agents-md-maintainer", + "handoff", + "improve-agent-readiness", + "iterative-retrieval", + "learn-from-code-review", + "mcp-builder", + "pdf", + "pdflatex", + "plain-english-content", + "pptx", + "release-notes", + "research", + "search-first", + "setup-agents-md", + "technical-writing", + "theme-factory", + "writing-for-agents", + "writing-skills", + "xlsx" + ], + "orchestration": [ + "add-javadoc", + "agent-memory", + "agent-readiness-report", + "discord", + "doc-coauthoring", + "docx", + "evidence-based-citations", + "find-skills", + "github-agents-md-maintainer", + "gpt-researcher", + "handoff", + "improve-agent-readiness", + "incident-retrospective", + "iterative-retrieval", + "learn-from-code-review", + "mcp-builder", + "notion", + "pdf", + "pdflatex", + "plain-english-content", + "pptx", + "release-notes", + "research", + "research-brief", + "search-first", + "setup-agents-md", + "slack-channel-monitor", + "slack-standup-digest", + "technical-writing", + "theme-factory", + "writing-for-agents", + "writing-skills", + "xlsx" + ], + "research": [ + "agent-memory", + "discord", + "doc-coauthoring", + "docx", + "evidence-based-citations", + "find-skills", + "github-agents-md-maintainer", + "gpt-researcher", + "handoff", + "incident-retrospective", + "iterative-retrieval", + "learn-from-code-review", + "notion", + "pdf", + "pdflatex", + "plain-english-content", + "pptx", + "research", + "research-brief", + "search-first", + "slack-channel-monitor", + "slack-standup-digest", + "technical-writing", + "theme-factory", + "writing-skills", + "xlsx" + ], + "extraction-caller": [ + "agent-memory", + "doc-coauthoring", + "docx", + "evidence-based-citations", + "find-skills", + "github-agents-md-maintainer", + "gpt-researcher", + "handoff", + "iterative-retrieval", + "learn-from-code-review", + "pdf", + "pdflatex", + "plain-english-content", + "pptx", + "research", + "research-brief", + "search-first", + "technical-writing", + "theme-factory", + "writing-skills", + "xlsx" + ] + }, + "research": { + "coding": [ + "find-skills", + "iterative-retrieval", + "jupyter", + "jupyter-notebook", + "research", + "search-first" + ], + "orchestration": [ + "find-skills", + "gpt-researcher", + "iterative-retrieval", + "news-digest", + "research", + "research-brief", + "search-first" + ], + "research": [ + "find-skills", + "gpt-researcher", + "iterative-retrieval", + "jupyter", + "jupyter-notebook", + "news-digest", + "research", + "research-brief", + "search-first" + ], + "extraction-caller": [ + "find-skills", + "gpt-researcher", + "iterative-retrieval", + "jupyter", + "jupyter-notebook", + "news-digest", + "research", + "research-brief", + "search-first" + ] + }, + "deployment-uv-docker": { + "coding": [ + "agent-canvas-environment", + "canvas-extension-api", + "deno", + "docker", + "kubernetes", + "modern-python", + "npm", + "ssh", + "swift-linux", + "uv", + "vercel", + "vercel-optimize" + ], + "orchestration": [ + "agent-canvas-environment", + "canvas-extension-api", + "deno", + "docker", + "kubernetes", + "modern-python", + "npm", + "ssh", + "swift-linux", + "uv", + "vercel", + "vercel-optimize" + ], + "research": [], + "extraction-caller": [ + "deno", + "docker", + "kubernetes", + "modern-python", + "npm", + "ssh", + "swift-linux", + "uv", + "vercel" + ] + }, + "memory": { + "coding": [ + "agent-memory", + "github-agents-md-maintainer", + "handoff", + "learn-from-code-review" + ], + "orchestration": [ + "agent-memory", + "discord", + "github-agents-md-maintainer", + "handoff", + "incident-retrospective", + "learn-from-code-review", + "notion", + "slack-channel-monitor", + "slack-standup-digest" + ], + "research": [ + "agent-memory", + "discord", + "github-agents-md-maintainer", + "handoff", + "incident-retrospective", + "learn-from-code-review", + "notion", + "slack-channel-monitor", + "slack-standup-digest" + ], + "extraction-caller": [ + "agent-memory", + "github-agents-md-maintainer", + "handoff", + "learn-from-code-review" + ] + } + }, + "gaps": [ + { + "scenario": "tdd", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "e2e-testing", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "code-review", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "security", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "github-issue-to-pr", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "github-issue-to-pr", + "role": "extraction-caller", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "github-pr-review", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "github-pr-review", + "role": "extraction-caller", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "github-ci-fix", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "github-ci-fix", + "role": "extraction-caller", + "reason": "The cell's only selection, verification-before-completion, is excluded since main removed it under M4 (#464); no other selected skill has a substantiated direct extraction-caller fit for CI repair. Route CI repair to a coding worker and measure that handoff." + }, + { + "scenario": "github-actions", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "github-actions", + "role": "extraction-caller", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "release-notes", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "release-notes", + "role": "extraction-caller", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + }, + { + "scenario": "deployment-uv-docker", + "role": "research", + "reason": "No selected skill has a substantiated direct role fit for this scenario; route implementation work to a coding worker and measure that handoff." + } + ], + "capability_gaps": [ + { + "scenario": "ab-testing-and-evaluation", + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "detail": "Skill-output A/B evaluation is covered by skill-creator. Product traffic allocation, power analysis and sequential testing have no qualified selected skill; do not equate these with blind output comparisons." + }, + { + "scenario": "research", + "roles": [ + "extraction-caller" + ], + "detail": "crawl4ai has a downloadable skill ZIP but no CLI-discoverable SKILL.md at inspected e5d2e786d1a101225f3f6a3e6fd344d76eeb13af. Caller research/citation skills do not certify crawler API correctness." + }, + { + "scenario": "memory", + "roles": [ + "coding", + "orchestration", + "research", + "extraction-caller" + ], + "detail": "Repository/document memory is covered. Automatic durable vector-memory services are not established by these skill installations." + } + ], + "collisions": [ + { + "name": "frontend-design", + "selected": { + "source": "anthropics/skills", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/frontend-design" + }, + "alternatives": [ + { + "source": "OpenHands/extensions", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/frontend-design" + } + ], + "reason": "Reuse the existing Anthropic pin by reference; do not replace it merely because another pack duplicates the name." + }, + { + "name": "code-review", + "selected": { + "source": "OpenHands/extensions", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/code-review" + }, + "alternatives": [ + { + "source": "mattpocock/skills", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "path": "skills/engineering/code-review" + } + ], + "reason": "OpenHands supplies native repository/acceptance-grounded risk review without requiring Matt-specific tracker setup; superpowers requesting/receiving stages remain separate names." + }, + { + "name": "linear", + "selected": { + "source": "OpenHands/extensions", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/linear" + }, + "alternatives": [ + { + "source": "openai/skills", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "path": "skills/.curated/linear" + } + ], + "reason": "OpenHands entry matches the automation and ticket-to-code skills in the same registry." + }, + { + "name": "release-notes", + "selected": { + "source": "OpenHands/extensions", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/release-notes" + }, + "alternatives": [ + { + "source": "OpenHands/extensions", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/release-notes" + } + ], + "reason": "Standalone OpenHands skill is usable without installing a plugin hook registry." + }, + { + "name": "theme-factory", + "selected": { + "source": "OpenHands/extensions", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/theme-factory" + }, + "alternatives": [ + { + "source": "anthropics/skills", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/theme-factory" + } + ], + "reason": "Keep the OpenHands registry entry for worker-native discovery; the Anthropic name would shadow it." + }, + { + "name": "skill-creator", + "selected": { + "source": "anthropics/skills", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/skill-creator" + }, + "alternatives": [ + { + "source": "OpenHands/extensions", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/skill-creator" + }, + { + "source": "openai/skills", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "path": "skills/.system/skill-creator" + } + ], + "reason": "Anthropic adds with/without-skill baselines, repeated benchmark statistics and blind A/B comparison needed for this trial." + }, + { + "name": "pdf", + "selected": { + "source": "anthropics/skills", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "path": "skills/pdf" + }, + "alternatives": [ + { + "source": "openai/skills", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "path": "skills/.curated/pdf" + } + ], + "reason": "Anthropic includes document-processing support resources suited to research/extraction artifacts; OpenAI is a same-name alternative." + } + ], + "excluded": [ + { + "name": "magic-word", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/magic-test/skills/magic-word", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/magic-test/skills/magic-word", + "tree_sha": "c3ece392a98726151242f57327fe0bfd643bfe77", + "skill_md_sha256": "4e57df560848c0061bc6b855f7cc82c94031eb7436d1fb2052d0655f49e3ffdb", + "skill_md_bytes": 910, + "description_chars": 78, + "upstream_disable_model_invocation": false, + "reason": "Magic-word activation fixture, not a production workflow." + }, + { + "name": "openhands", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/openhands", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/openhands", + "tree_sha": "8806d3fa278fcc60f35eaba7aff3df1fb1cd48dc", + "skill_md_sha256": "82e08c6108bc07c2b7996fd0b70282154fd23256eb45ced1e7e9dab947b22749", + "skill_md_bytes": 2899, + "description_chars": 284, + "upstream_disable_model_invocation": false, + "reason": "Plugin bundle entrypoint with CLI/MCP/plugin wiring; select its individual SDK/API/automation skills instead. A SKILL.md installation does not activate the plugin." + }, + { + "name": "release-notes", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/plugins/release-notes", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "plugins/release-notes", + "tree_sha": "db732a58a016444fd45339c2a15188f44a61f87a", + "skill_md_sha256": "bf3b595334efcf2674d47e358aedc7c43af3085dd6d715ac64dd6ce56ce12abd", + "skill_md_bytes": 3868, + "description_chars": 231, + "upstream_disable_model_invocation": false, + "reason": "Name collision: choose skills/release-notes, the standalone history-to-changelog procedure; plugin hooks are not installed by this CLI." + }, + { + "name": "add-skill", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/add-skill", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/add-skill", + "tree_sha": "c4eeeeb4bc0a3e008aca42472f01bac6f2bb4523", + "skill_md_sha256": "dfe7467e03adfcbca1cb2dd6db40d552a57584ad13c0abed311f82d25e5bd88c", + "skill_md_bytes": 2243, + "description_chars": 518, + "upstream_disable_model_invocation": false, + "reason": "Fetches and writes skills with its own Python copier; incompatible with the required upstream skills CLI lifecycle. find-skills plus the extended installer own this operation." + }, + { + "name": "flarglebargle", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/flarglebargle", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/flarglebargle", + "tree_sha": "e334839d21ac8575062a6703e9de7771a06e6e0d", + "skill_md_sha256": "4abf0757e97eeb1163d8864a8955223430f5d977fe5b40c682d3640659cc7832", + "skill_md_bytes": 337, + "description_chars": 139, + "upstream_disable_model_invocation": false, + "reason": "Compliment-only activation fixture; no production role/scenario. Retain upstream as an optional smoke-test reference, not a worker instruction." + }, + { + "name": "frontend-design", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/frontend-design", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/frontend-design", + "tree_sha": "b0a4c7e2bfe269096dade735b9b0ea83bcb17373", + "skill_md_sha256": "982cecaaf2a95a76d0bbebe8ff5570ea9e23088535fee54f90417f7b562545ad", + "skill_md_bytes": 4443, + "description_chars": 399, + "upstream_disable_model_invocation": false, + "reason": "Name collision: keep the already pinned anthropics/skills source by reference; same design domain, avoids shadowing the adopted entry." + }, + { + "name": "skill-creator", + "source": "OpenHands/extensions", + "url": "https://github.com/OpenHands/extensions/tree/bea7a20c59c44ec4dacddac3fc0efe58b9c73880/skills/skill-creator", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "path": "skills/skill-creator", + "tree_sha": "9e4ffbdc8c0db2c16b223144a8716f9d8c9f6c08", + "skill_md_sha256": "651c6a4db39a16d3a58ee4559ec52209aefc097f58bfa32dd4a24ba4f285fbb2", + "skill_md_bytes": 20969, + "description_chars": 386, + "upstream_disable_model_invocation": false, + "reason": "Name collision: choose anthropics/skills skill-creator for baseline runs, benchmarks and blind comparison, closing the skill-evaluation gap." + }, + { + "name": "security-audit", + "source": "cloudflare/security-audit-skill", + "adoption_ref": "adoption/skills/manifest.json", + "reason": "Main gates this adoption skill: #448 (8315274f) keeps Codex disabled (codex_enabled false) and the Claude listing name-only pending the M5c bake-off against /security-review. Reusing it here would install it for runtime workers without that gate.", + "overturn": "Main promotes security-audit after M5c, that is adoption/skills/manifest.json sets codex_enabled true or claude_listing on: replace this exclusion with a reuse_ref entry and assign its scenarios and roles. Any other change to main's gate on it also fails the exclusion test and needs a new review." + }, + { + "name": "verification-before-completion", + "source": "obra/superpowers", + "url": "https://github.com/obra/superpowers/tree/8ca22dba9a94f28898bbce59f2537ff4d87c747d/skills/verification-before-completion", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "path": "skills/verification-before-completion", + "tree_sha": "a4cb0b69aaefeab540947a7f1642bdaad810e37a", + "skill_md_sha256": "2befe7fc55bcadaa3d97dd9e8efeb633d2561c0ebe74c5a8b17c4d9e7e4520b3", + "skill_md_bytes": 3646, + "description_chars": 225, + "upstream_disable_model_invocation": false, + "reason": "Main removed it from its skills trial under the conflict rule M4 (#464, c0966da2; decision docs/decisions/2026-09-28-delegated-decisions.md, #462) and lists it under its own excluded. Its SKILL.md at this pin requires a fresh run of the verification command before any completion claim and rates a previous run as not sufficient (L17-20, L42), which conflicts with AGENTS.md:16, \"Reuse passing evidence when its inputs still match\". A worker whose work directory is a checkout of this repository loads that AGENTS.md too: OpenHands with project loading on reads it from the work directory and the Git root (skill.py:1084-1106 at fcc102a6), and Claude Code imports it through CLAUDE.md's first line, @AGENTS.md. Main no longer lists it among its skills, so this exclusion carries no adoption_ref; the pin fields record the revision main read.", + "overturn": "Main re-admits it, that is adoption/skills/manifest.json lists verification-before-completion under skills again (main's own overturn: an upstream revision drops the absolute freshness requirement, is re-read in full and is re-pinned there). Then replace this exclusion with a reuse_ref entry at main's pin and restore its scenarios (tdd, github-ci-fix, code-review) and roles (coding, orchestration, extraction-caller). test_verification_before_completion_stays_excluded_until_main_readmits_it and the coverage contract both fail as soon as main re-admits it." + } + ], + "openhands_inventory": [ + { + "name": "build-setup", + "path": "plugins/cobol-modernization/skills/build-setup", + "selected": true + }, + { + "name": "cobol-modernization", + "path": "plugins/cobol-modernization/skills/cobol-modernization", + "selected": true + }, + { + "name": "mainframe-planning", + "path": "plugins/cobol-modernization/skills/mainframe-planning", + "selected": true + }, + { + "name": "mainframe-removal", + "path": "plugins/cobol-modernization/skills/mainframe-removal", + "selected": true + }, + { + "name": "to-java-migration", + "path": "plugins/cobol-modernization/skills/to-java-migration", + "selected": true + }, + { + "name": "magic-word", + "path": "plugins/magic-test/skills/magic-word", + "selected": false + }, + { + "name": "migration-mapping", + "path": "plugins/migration-scoring/skills/migration-mapping", + "selected": true + }, + { + "name": "migration-report", + "path": "plugins/migration-scoring/skills/migration-report", + "selected": true + }, + { + "name": "migration-scoring", + "path": "plugins/migration-scoring/skills/migration-scoring", + "selected": true + }, + { + "name": "score-quality", + "path": "plugins/migration-scoring/skills/score-quality", + "selected": true + }, + { + "name": "score-style", + "path": "plugins/migration-scoring/skills/score-style", + "selected": true + }, + { + "name": "agent-readiness-report", + "path": "plugins/onboarding/skills/agent-readiness-report", + "selected": true + }, + { + "name": "improve-agent-readiness", + "path": "plugins/onboarding/skills/improve-agent-readiness", + "selected": true + }, + { + "name": "setup-agents-md", + "path": "plugins/onboarding/skills/setup-agents-md", + "selected": true + }, + { + "name": "setup-openhands", + "path": "plugins/onboarding/skills/setup-openhands", + "selected": true + }, + { + "name": "setup-pr-review", + "path": "plugins/onboarding/skills/setup-pr-review", + "selected": true + }, + { + "name": "openhands", + "path": "plugins/openhands", + "selected": false + }, + { + "name": "release-notes", + "path": "plugins/release-notes", + "selected": false + }, + { + "name": "add-javadoc", + "path": "skills/add-javadoc", + "selected": true + }, + { + "name": "add-skill", + "path": "skills/add-skill", + "selected": false + }, + { + "name": "agent-canvas-environment", + "path": "skills/agent-canvas-environment", + "selected": true + }, + { + "name": "agent-creator", + "path": "skills/agent-creator", + "selected": true + }, + { + "name": "agent-memory", + "path": "skills/agent-memory", + "selected": true + }, + { + "name": "agent-sdk-builder", + "path": "skills/agent-sdk-builder", + "selected": true + }, + { + "name": "azure-devops", + "path": "skills/azure-devops", + "selected": true + }, + { + "name": "bitbucket", + "path": "skills/bitbucket", + "selected": true + }, + { + "name": "bitbucket-cloud", + "path": "skills/bitbucket-cloud", + "selected": true + }, + { + "name": "bitbucket-data-center", + "path": "skills/bitbucket-data-center", + "selected": true + }, + { + "name": "canvas-extension-api", + "path": "skills/canvas-extension-api", + "selected": true + }, + { + "name": "code-review", + "path": "skills/code-review", + "selected": true + }, + { + "name": "code-simplifier", + "path": "skills/code-simplifier", + "selected": true + }, + { + "name": "datadog", + "path": "skills/datadog", + "selected": true + }, + { + "name": "deno", + "path": "skills/deno", + "selected": true + }, + { + "name": "discord", + "path": "skills/discord", + "selected": true + }, + { + "name": "docker", + "path": "skills/docker", + "selected": true + }, + { + "name": "evidence-based-citations", + "path": "skills/evidence-based-citations", + "selected": true + }, + { + "name": "flarglebargle", + "path": "skills/flarglebargle", + "selected": false + }, + { + "name": "frontend-design", + "path": "skills/frontend-design", + "selected": false + }, + { + "name": "github", + "path": "skills/github", + "selected": true + }, + { + "name": "github-actions", + "path": "skills/github-actions", + "selected": true + }, + { + "name": "github-agents-md-maintainer", + "path": "skills/github-agents-md-maintainer", + "selected": true + }, + { + "name": "github-delivery-watchdog", + "path": "skills/github-delivery-watchdog", + "selected": true + }, + { + "name": "github-issue-to-pr", + "path": "skills/github-issue-to-pr", + "selected": true + }, + { + "name": "github-issue-triage", + "path": "skills/github-issue-triage", + "selected": true + }, + { + "name": "github-pr-review", + "path": "skills/github-pr-review", + "selected": true + }, + { + "name": "github-pr-reviewer", + "path": "skills/github-pr-reviewer", + "selected": true + }, + { + "name": "github-repo-monitor", + "path": "skills/github-repo-monitor", + "selected": true + }, + { + "name": "github-stale-ci-pr-closer", + "path": "skills/github-stale-ci-pr-closer", + "selected": true + }, + { + "name": "gitlab", + "path": "skills/gitlab", + "selected": true + }, + { + "name": "gitlab-issue-to-mr", + "path": "skills/gitlab-issue-to-mr", + "selected": true + }, + { + "name": "incident-retrospective", + "path": "skills/incident-retrospective", + "selected": true + }, + { + "name": "iterate", + "path": "skills/iterate", + "selected": true + }, + { + "name": "jira-issue-to-pr", + "path": "skills/jira-issue-to-pr", + "selected": true + }, + { + "name": "jupyter", + "path": "skills/jupyter", + "selected": true + }, + { + "name": "kubernetes", + "path": "skills/kubernetes", + "selected": true + }, + { + "name": "learn-from-code-review", + "path": "skills/learn-from-code-review", + "selected": true + }, + { + "name": "linear", + "path": "skills/linear", + "selected": true + }, + { + "name": "linear-triage", + "path": "skills/linear-triage", + "selected": true + }, + { + "name": "news-digest", + "path": "skills/news-digest", + "selected": true + }, + { + "name": "notion", + "path": "skills/notion", + "selected": true + }, + { + "name": "npm", + "path": "skills/npm", + "selected": true + }, + { + "name": "openhands-api", + "path": "skills/openhands-api", + "selected": true + }, + { + "name": "openhands-automation", + "path": "skills/openhands-automation", + "selected": true + }, + { + "name": "openhands-enterprise-troubleshooting", + "path": "skills/openhands-enterprise-troubleshooting", + "selected": true + }, + { + "name": "openhands-sdk", + "path": "skills/openhands-sdk", + "selected": true + }, + { + "name": "pdflatex", + "path": "skills/pdflatex", + "selected": true + }, + { + "name": "plain-english-content", + "path": "skills/plain-english-content", + "selected": true + }, + { + "name": "prd", + "path": "skills/prd", + "selected": true + }, + { + "name": "qa-changes", + "path": "skills/qa-changes", + "selected": true + }, + { + "name": "release-notes", + "path": "skills/release-notes", + "selected": true + }, + { + "name": "research-brief", + "path": "skills/research-brief", + "selected": true + }, + { + "name": "security", + "path": "skills/security", + "selected": true + }, + { + "name": "skill-creator", + "path": "skills/skill-creator", + "selected": false + }, + { + "name": "slack-channel-monitor", + "path": "skills/slack-channel-monitor", + "selected": true + }, + { + "name": "slack-standup-digest", + "path": "skills/slack-standup-digest", + "selected": true + }, + { + "name": "spark-version-upgrade", + "path": "skills/spark-version-upgrade", + "selected": true + }, + { + "name": "ssh", + "path": "skills/ssh", + "selected": true + }, + { + "name": "swift-linux", + "path": "skills/swift-linux", + "selected": true + }, + { + "name": "technical-writing", + "path": "skills/technical-writing", + "selected": true + }, + { + "name": "theme-factory", + "path": "skills/theme-factory", + "selected": true + }, + { + "name": "ticket-to-code-change", + "path": "skills/ticket-to-code-change", + "selected": true + }, + { + "name": "upstream-fork-sync", + "path": "skills/upstream-fork-sync", + "selected": true + }, + { + "name": "uv", + "path": "skills/uv", + "selected": true + }, + { + "name": "vercel", + "path": "skills/vercel", + "selected": true + } + ], + "sources": [ + { + "source": "OpenHands/extensions", + "ref": "bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "resolved_via": "gh api repos/OpenHands/extensions/commits/bea7a20c59c44ec4dacddac3fc0efe58b9c73880", + "commit_date": "2026-09-27T12:29:58Z", + "selected_skills": 77, + "tree_response_truncated": false + }, + { + "source": "affaan-m/ECC", + "ref": "2b6e839771e53096d8451a213d40dc64ec8acac0", + "resolved_via": "gh api repos/affaan-m/ECC/commits/2b6e839771e53096d8451a213d40dc64ec8acac0", + "commit_date": "2026-09-20T19:37:57Z", + "selected_skills": 2, + "tree_response_truncated": false + }, + { + "source": "anthropics/skills", + "ref": "33375500bcea98d610eb30ce10ac4e59b89c390d", + "resolved_via": "gh api repos/anthropics/skills/commits/33375500bcea98d610eb30ce10ac4e59b89c390d", + "commit_date": "2026-09-24T16:20:35Z", + "selected_skills": 9, + "tree_response_truncated": false + }, + { + "source": "assafelovic/gpt-researcher", + "ref": "0957c301ed06c2a5857b834358c7227c739041d4", + "resolved_via": "gh api repos/assafelovic/gpt-researcher/commits/0957c301ed06c2a5857b834358c7227c739041d4", + "commit_date": "2026-09-26T16:56:07Z", + "selected_skills": 1, + "tree_response_truncated": false + }, + { + "source": "mattpocock/skills", + "ref": "c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "resolved_via": "gh api repos/mattpocock/skills/commits/c55ee46073ed923f86ce59a5eb3b6d895095d1b7", + "commit_date": "2026-09-18T10:12:29Z", + "selected_skills": 12, + "tree_response_truncated": false + }, + { + "source": "obra/superpowers", + "ref": "8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "resolved_via": "gh api repos/obra/superpowers/commits/8ca22dba9a94f28898bbce59f2537ff4d87c747d", + "commit_date": "2026-09-25T18:06:27Z", + "selected_skills": 14, + "tree_response_truncated": false + }, + { + "source": "openai/skills", + "ref": "49f948faa9258a0c61caceaf225e179651397431", + "resolved_via": "gh api repos/openai/skills/commits/49f948faa9258a0c61caceaf225e179651397431", + "commit_date": "2026-06-24T02:36:12Z", + "selected_skills": 6, + "tree_response_truncated": false + }, + { + "source": "trailofbits/skills", + "ref": "0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "resolved_via": "gh api repos/trailofbits/skills/commits/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae", + "commit_date": "2026-09-24T18:57:03Z", + "selected_skills": 9, + "tree_response_truncated": false + }, + { + "source": "typesafe-ai/skills", + "ref": "65a39f393687675ce170e6094757de20370365b9", + "resolved_via": "gh api repos/typesafe-ai/skills/commits/65a39f393687675ce170e6094757de20370365b9", + "commit_date": "2026-09-12T05:42:05Z", + "selected_skills": 1, + "tree_response_truncated": false + }, + { + "source": "vercel-labs/agent-browser", + "ref": "d01253d9db28d75080e36da3c1c31ef89454731e", + "resolved_via": "gh api repos/vercel-labs/agent-browser/commits/d01253d9db28d75080e36da3c1c31ef89454731e", + "commit_date": "2026-09-22T13:50:02Z", + "selected_skills": 1, + "tree_response_truncated": false + }, + { + "source": "vercel-labs/agent-skills", + "ref": "063bee94c3f4df8453406c830b0a7df0f2860278", + "resolved_via": "gh api repos/vercel-labs/agent-skills/commits/063bee94c3f4df8453406c830b0a7df0f2860278", + "commit_date": "2026-08-28T13:36:07Z", + "selected_skills": 4, + "tree_response_truncated": false + }, + { + "source": "vercel-labs/skills", + "ref": "7407f3893ad4dceab546ac002c3ef806e4000c73", + "resolved_via": "gh api repos/vercel-labs/skills/commits/7407f3893ad4dceab546ac002c3ef806e4000c73", + "commit_date": "2026-09-17T15:00:17Z", + "selected_skills": 1, + "tree_response_truncated": false + } + ], + "budget": { + "selected_count": 137, + "skill_md_bytes": 1020955, + "description_chars": 36739, + "provider_input_tokens_before": null, + "provider_input_tokens_after": null, + "meaning": "Catalog byte/character sums only, not first-prompt tokens. Measure native requests as specified in README." + } +} diff --git a/manifests/evidence.json b/manifests/evidence.json index 8868446ba..bb033f048 100644 --- a/manifests/evidence.json +++ b/manifests/evidence.json @@ -5587,8 +5587,8 @@ }, { "path": "blueprints/convergence-practice/omniroute-runtime-enhancements/experiment.json", - "sha256": "005582b16d21b0ad7cfa85857d222baf598badc74d929a82b3da7c2b0dd39d55", - "bytes": 29633 + "sha256": "819124da985301f216fd0e3178d7b1aa4986e0c3812d18a75505723d85dbdfcc", + "bytes": 29678 }, { "path": "blueprints/convergence-practice/omniroute-runtime-workers/experiment.json", @@ -35325,6 +35325,11 @@ "sha256": "7b49b6e997017b1cde21f9aa33af3d5510926ad182f3211d0dd40cd71762a44a", "bytes": 179 }, + { + "path": "evidence/artifacts/omniroute-runtime-enhancements-20260930/selected-skills-manifest.json.txt", + "sha256": "3bc75e2e29e624de301227da157d427d81f1590526f837bb7a0c4b74f0b65439", + "bytes": 186305 + }, { "path": "evidence/artifacts/omniroute-runtime-workers-20260930/pre-enhancement-dispatcher.md", "sha256": "857a00f0c3f4088a20662f32f422b30c4697d0c267c0db1f9dbb95dfcbe39ce5",