Skip to content

fix(codex): auto-enable harness plugin for forced runtime#67474

Merged
steipete merged 3 commits into
openclaw:mainfrom
duqaXxX:fix/codex-harness-startup-activation-v2026.4.14
Apr 16, 2026
Merged

fix(codex): auto-enable harness plugin for forced runtime#67474
steipete merged 3 commits into
openclaw:mainfrom
duqaXxX:fix/codex-harness-startup-activation-v2026.4.14

Conversation

@duqaXxX

@duqaXxX duqaXxX commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Summary

When agents.defaults.embeddedHarness.runtime is forced to codex, OpenClaw can start the Codex harness without activating the Codex plugin first. That leaves the runtime selected but its harness-owned plugin functionality unavailable at startup.

This PR closes that gap by treating configured embedded harness runtimes as plugin auto-enable signals and by letting plugin manifests declare ownership of specific agent harness runtimes.

What changed

  • add Codex plugin manifest activation metadata for the codex harness runtime
  • detect configured embedded harness runtimes from defaults, per-agent config, and OPENCLAW_AGENT_RUNTIME
  • auto-enable plugins whose manifests declare activation.onAgentHarnesses
  • extend activation planning so harness-runtime triggers match manifest activation rules
  • add coverage for manifest lookup, auto-enable resolution, channel plugin ids, and activation planning

Files in scope

  • extensions/codex/openclaw.plugin.json
  • src/config/plugin-auto-enable.core.test.ts
  • src/config/plugin-auto-enable.shared.ts
  • src/config/plugin-auto-enable.test-helpers.ts
  • src/config/plugin-auto-enable.types.ts
  • src/plugins/activation-planner.test.ts
  • src/plugins/activation-planner.ts
  • src/plugins/channel-plugin-ids.test.ts
  • src/plugins/channel-plugin-ids.ts
  • src/plugins/manifest.ts

Non-goals

  • no changes to logging surface behavior
  • no attempt to address the separate logging-surface issue diagnosed tonight
  • no broader runtime-selection or startup-flow refactor beyond the existing branch contents

Validation

  • publication only in this step; no additional local code changes were made for this PR
  • immediate CI status will be checked after PR creation

@greptile-apps

greptile-apps Bot commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR wires up the previously-inert onAgentHarnesses manifest field so that when agents.defaults.embeddedHarness.runtime (or per-agent config / OPENCLAW_AGENT_RUNTIME) is forced to codex, the Codex plugin is both auto-enabled in config and included in the gateway startup scope. The two-layer approach — applyPluginAutoEnable at config-load time and resolveGatewayStartupPluginIds at startup — is correctly seeded from the activationSourceConfig (pre-auto-enable snapshot) to avoid double-counting.

The remaining findings are P2 style notes: near-identical harness runtime collection functions in two modules, and a missing test for the OPENCLAW_AGENT_RUNTIME env-var trigger path.

Confidence Score: 5/5

Safe to merge — the logic is correct end-to-end, tests cover the primary config-driven paths, and no P0/P1 issues were found.

All remaining findings are P2 style/quality suggestions (duplicated helper function and a missing env-var test case). The core activation and startup logic is sound and well-tested.

No files require special attention, though src/config/plugin-auto-enable.shared.ts and src/plugins/channel-plugin-ids.ts share near-identical harness-runtime collection logic that is worth consolidating in a follow-up.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/config/plugin-auto-enable.shared.ts
Line: 102-127

Comment:
**Duplicated harness runtime collection logic**

`collectEmbeddedHarnessRuntimes` here and `collectRequestedAgentHarnessRuntimes` in `channel-plugin-ids.ts` (lines 53–78) are near-identical implementations — same three sources (`agents.defaults`, `agents.list[*]`, `OPENCLAW_AGENT_RUNTIME`), same "auto"/"pi" exclusion, same deduplication. They differ only in the agent-list entry guard (`isRecord` vs. an explicit object check). If the filtering logic ever changes (e.g., a new excluded runtime name), both copies need to be updated in sync. A shared utility at a neutral boundary (e.g., `src/agents/harness-runtimes.ts`) would keep the two call sites consistent.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/config/plugin-auto-enable.core.test.ts
Line: 220-248

Comment:
**Missing test for `OPENCLAW_AGENT_RUNTIME` auto-enable path**

The new test covers the config-driven path (`agents.defaults.embeddedHarness.runtime`), but the third source in `collectEmbeddedHarnessRuntimes``env.OPENCLAW_AGENT_RUNTIME` — has no test in this file. Since `makeIsolatedEnv()` doesn't set that variable, a user who relies on the env-var path to force the codex runtime would not be covered. A companion case passing `makeIsolatedEnv({ OPENCLAW_AGENT_RUNTIME: "codex" })` would close the gap.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(codex): activate harness plugin for ..." | Re-trigger Greptile

Comment thread src/config/plugin-auto-enable.shared.ts Outdated
Comment on lines +102 to +127
function collectEmbeddedHarnessRuntimes(cfg: OpenClawConfig, env: NodeJS.ProcessEnv): string[] {
const runtimes = new Set<string>();
const pushRuntime = (value: unknown) => {
if (typeof value !== "string") {
return;
}
const normalized = normalizeOptionalLowercaseString(value);
if (!normalized || normalized === "auto" || normalized === "pi") {
return;
}
runtimes.add(normalized);
};

pushRuntime(cfg.agents?.defaults?.embeddedHarness?.runtime);
if (Array.isArray(cfg.agents?.list)) {
for (const agent of cfg.agents.list) {
if (!isRecord(agent)) {
continue;
}
pushRuntime((agent.embeddedHarness as Record<string, unknown> | undefined)?.runtime);
}
}
pushRuntime(env.OPENCLAW_AGENT_RUNTIME);

return [...runtimes].toSorted((left, right) => left.localeCompare(right));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Duplicated harness runtime collection logic

collectEmbeddedHarnessRuntimes here and collectRequestedAgentHarnessRuntimes in channel-plugin-ids.ts (lines 53–78) are near-identical implementations — same three sources (agents.defaults, agents.list[*], OPENCLAW_AGENT_RUNTIME), same "auto"/"pi" exclusion, same deduplication. They differ only in the agent-list entry guard (isRecord vs. an explicit object check). If the filtering logic ever changes (e.g., a new excluded runtime name), both copies need to be updated in sync. A shared utility at a neutral boundary (e.g., src/agents/harness-runtimes.ts) would keep the two call sites consistent.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/config/plugin-auto-enable.shared.ts
Line: 102-127

Comment:
**Duplicated harness runtime collection logic**

`collectEmbeddedHarnessRuntimes` here and `collectRequestedAgentHarnessRuntimes` in `channel-plugin-ids.ts` (lines 53–78) are near-identical implementations — same three sources (`agents.defaults`, `agents.list[*]`, `OPENCLAW_AGENT_RUNTIME`), same "auto"/"pi" exclusion, same deduplication. They differ only in the agent-list entry guard (`isRecord` vs. an explicit object check). If the filtering logic ever changes (e.g., a new excluded runtime name), both copies need to be updated in sync. A shared utility at a neutral boundary (e.g., `src/agents/harness-runtimes.ts`) would keep the two call sites consistent.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +220 to +248
it("auto-enables an opt-in plugin when an embedded agent harness runtime is configured", () => {
const result = applyPluginAutoEnable({
config: {
agents: {
defaults: {
embeddedHarness: {
runtime: "codex",
fallback: "none",
},
},
},
},
env: makeIsolatedEnv(),
manifestRegistry: makeRegistry([
{
id: "codex",
channels: [],
activation: {
onAgentHarnesses: ["codex"],
},
},
]),
});

expect(result.config.plugins?.entries?.codex?.enabled).toBe(true);
expect(result.changes).toContain(
"codex agent harness runtime configured, enabled automatically.",
);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Missing test for OPENCLAW_AGENT_RUNTIME auto-enable path

The new test covers the config-driven path (agents.defaults.embeddedHarness.runtime), but the third source in collectEmbeddedHarnessRuntimesenv.OPENCLAW_AGENT_RUNTIME — has no test in this file. Since makeIsolatedEnv() doesn't set that variable, a user who relies on the env-var path to force the codex runtime would not be covered. A companion case passing makeIsolatedEnv({ OPENCLAW_AGENT_RUNTIME: "codex" }) would close the gap.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/config/plugin-auto-enable.core.test.ts
Line: 220-248

Comment:
**Missing test for `OPENCLAW_AGENT_RUNTIME` auto-enable path**

The new test covers the config-driven path (`agents.defaults.embeddedHarness.runtime`), but the third source in `collectEmbeddedHarnessRuntimes``env.OPENCLAW_AGENT_RUNTIME` — has no test in this file. Since `makeIsolatedEnv()` doesn't set that variable, a user who relies on the env-var path to force the codex runtime would not be covered. A companion case passing `makeIsolatedEnv({ OPENCLAW_AGENT_RUNTIME: "codex" })` would close the gap.

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4299fe4580

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +330 to +334
if (requiredAgentHarnessPluginIds.has(plugin.id)) {
const activationState = resolveEffectivePluginActivationState({
id: plugin.id,
origin: plugin.origin,
config: pluginsConfig,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Preserve explicit gating for non-bundled harness plugins

This new early-return path loads any plugin matched by onAgentHarnesses as soon as activationState.enabled is true, which bypasses the non-bundled startup gate later in this function (plugin.origin !== "bundled" requiring explicit enablement). In practice, a workspace/global plugin can now be loaded at startup by just declaring activation.onAgentHarnesses: ["codex"] and having agents.*.embeddedHarness.runtime=codex, even when the plugin was never explicitly enabled. That is a behavior and trust-model regression versus the prior startup policy.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3b170fe54

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +142 to +145
.filter((plugin) =>
(plugin.activation?.onAgentHarnesses ?? []).some(
(entry) => normalizeOptionalLowercaseString(entry) === normalizedRuntime,
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Restrict harness-runtime auto-enable to trusted origins

resolveAgentHarnessOwnerPluginIds matches any plugin manifest that declares activation.onAgentHarnesses for a runtime, but it does not filter by origin or trust policy. That candidate set is then auto-materialized into plugins.entries.<id>.enabled=true, so forcing a runtime like codex can auto-enable a workspace/global plugin that only advertises onAgentHarnesses: ["codex"] even when the user never explicitly enabled it. This creates a startup/runtime trust regression for non-bundled plugins and should be constrained similarly to other bundled-only auto-enable paths.

Useful? React with 👍 / 👎.

@steipete
steipete force-pushed the fix/codex-harness-startup-activation-v2026.4.14 branch from f3b170f to 2aaaa64 Compare April 16, 2026 15:59
@openclaw-barnacle openclaw-barnacle Bot added the agents Agent runtime and tooling label Apr 16, 2026
@steipete
steipete merged commit 86f1084 into openclaw:main Apr 16, 2026
45 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Landed via rebase merge.

Source/head: 2aaaa64fd5204a71bc4fc686a3bb6ce0af18372d
Main: 86f108401bcdc3e03ca5bb6cf8299c21156ae6f3

Review follow-up included:

  • Factored agent harness runtime collection into shared src/agents/harness-runtimes.ts.
  • Added OPENCLAW_AGENT_RUNTIME=codex coverage for auto-enable and startup plugin ID resolution.

Gates:

  • pnpm test src/config/plugin-auto-enable.core.test.ts src/plugins/channel-plugin-ids.test.ts src/plugins/activation-planner.test.ts
  • pnpm check
  • pnpm build
  • PR CI green

xudaiyanzi pushed a commit to xudaiyanzi/openclaw that referenced this pull request Apr 17, 2026
kvnkho pushed a commit to kvnkho/openclaw that referenced this pull request Apr 17, 2026
Mquarmoc pushed a commit to Mquarmoc/openclaw that referenced this pull request Apr 20, 2026
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
globalcaos pushed a commit to globalcaos/tinkerclaw that referenced this pull request May 13, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling extensions: codex size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants