fix(agents): honor skipBootstrap at runtime injection path (#75184)#75217
fix(agents): honor skipBootstrap at runtime injection path (#75184)#75217lonexreb wants to merge 5 commits intoopenclaw:mainfrom
Conversation
|
Codex review: needs real behavior proof before merge. Summary Reproducibility: yes. for source-level reproduction: current main loads workspace bootstrap files in Real behavior proof Next step before merge Security Review findings
Review detailsBest possible solution: Land the resolver-level workspace-file skip with hook preservation after adding schema/help/label/generated metadata, a changelog Fixes entry, and real Do we have a high-confidence way to reproduce the issue? Yes for source-level reproduction: current main loads workspace bootstrap files in Is this the best way to solve the issue? No, not yet. The resolver-level boundary and hook-preserving approach are the right maintainable direction, but schema metadata, changelog, and real behavior proof still need to be completed before merge. Full review comments:
Overall correctness: patch is incorrect What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 7d5ca3064a51. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a69ba75e9d
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (params.config?.agents?.defaults?.skipBootstrap === true) { | ||
| return []; | ||
| } |
There was a problem hiding this comment.
Keep bootstrap hooks active when skipBootstrap is enabled
This early return bypasses applyBootstrapHookOverrides, so agent:bootstrap hooks never run when agents.defaults.skipBootstrap is true. That is a behavior regression for setups that skip default workspace bootstrap files but still rely on hook-provided context (for example the bundled bootstrap-extra-files handler in src/hooks/bundled/bootstrap-extra-files/handler.ts:25), because those injected files now disappear from runtime prompt assembly.
Useful? React with 👍 / 👎.
…for existing workspace files Codex review on PR openclaw#75217 noted that the runtime resolver guard correctly honors agents.defaults.skipBootstrap, but the public docs at docs/gateway/config-agents.md still described it as workspace-creation-only, and the diff did not include a regression proving `contextFiles` / `injectedWorkspaceFiles` stay empty when existing workspace files are present and skipBootstrap is true. Align the public contract with the new runtime behavior: - docs/gateway/config-agents.md now describes both effects of skipBootstrap (creation + runtime injection) and points users at `contextInjection: 'never'` if they want to keep files on disk but skip injection only. - src/config/types.agent-defaults.ts JSDoc on `skipBootstrap` mirrors the doc wording so editor hover and SDK consumers see the same contract. Add a regression in src/agents/bootstrap-files.test.ts that exercises the exact failure mode the issue described: write AGENTS.md and SOUL.md into the workspace, then call resolveBootstrapFilesForRun and resolveBootstrapContextForRun with skipBootstrap=true and assert both return empty results. A second case sets skipBootstrap=false / unset and asserts AGENTS.md is still resolved, so the guard does not regress the default path. Refs openclaw#75184
|
Round-1 review addressed in 4dcbde0. The bot was right that the public config contract had drifted from the new runtime behavior, and that the diff lacked a regression for the existing-workspace-files case. Changes:
Acceptance criteria checked locally:
PTAL. |
…for existing workspace files Codex review on PR openclaw#75217 noted that the runtime resolver guard correctly honors agents.defaults.skipBootstrap, but the public docs at docs/gateway/config-agents.md still described it as workspace-creation-only, and the diff did not include a regression proving `contextFiles` / `injectedWorkspaceFiles` stay empty when existing workspace files are present and skipBootstrap is true. Align the public contract with the new runtime behavior: - docs/gateway/config-agents.md now describes both effects of skipBootstrap (creation + runtime injection) and points users at `contextInjection: 'never'` if they want to keep files on disk but skip injection only. - src/config/types.agent-defaults.ts JSDoc on `skipBootstrap` mirrors the doc wording so editor hover and SDK consumers see the same contract. Add a regression in src/agents/bootstrap-files.test.ts that exercises the exact failure mode the issue described: write AGENTS.md and SOUL.md into the workspace, then call resolveBootstrapFilesForRun and resolveBootstrapContextForRun with skipBootstrap=true and assert both return empty results. A second case sets skipBootstrap=false / unset and asserts AGENTS.md is still resolved, so the guard does not regress the default path. Refs openclaw#75184
4dcbde0 to
25ee550
Compare
|
Addressed [P2] from codex review ( Re-review progress:
|
…for existing workspace files Codex review on PR openclaw#75217 noted that the runtime resolver guard correctly honors agents.defaults.skipBootstrap, but the public docs at docs/gateway/config-agents.md still described it as workspace-creation-only, and the diff did not include a regression proving `contextFiles` / `injectedWorkspaceFiles` stay empty when existing workspace files are present and skipBootstrap is true. Align the public contract with the new runtime behavior: - docs/gateway/config-agents.md now describes both effects of skipBootstrap (creation + runtime injection) and points users at `contextInjection: 'never'` if they want to keep files on disk but skip injection only. - src/config/types.agent-defaults.ts JSDoc on `skipBootstrap` mirrors the doc wording so editor hover and SDK consumers see the same contract. Add a regression in src/agents/bootstrap-files.test.ts that exercises the exact failure mode the issue described: write AGENTS.md and SOUL.md into the workspace, then call resolveBootstrapFilesForRun and resolveBootstrapContextForRun with skipBootstrap=true and assert both return empty results. A second case sets skipBootstrap=false / unset and asserts AGENTS.md is still resolved, so the guard does not regress the default path. Refs openclaw#75184
25ee550 to
3384452
Compare
…enabled Codex follow-up on PR openclaw#75217 noted: the early return when agents.defaults.skipBootstrap was true bypassed applyBootstrapHookOverrides entirely, so agent:bootstrap hooks (e.g. the bundled bootstrap-extra-files handler in src/hooks/bundled/bootstrap-extra-files/handler.ts) never ran when the flag was set. That broke installations that opt out of default workspace bootstrap files but still rely on hook-injected context. skipBootstrap is meant to suppress only the WORKSPACE bootstrap files — hooks should still run. Skip the workspace file load when the flag is set and feed an empty file list into applyBootstrapHookOverrides; hooks can then return their own files which we sanitize and return like any other bootstrap result. Add a regression test that registers an agent:bootstrap hook, sets skipBootstrap to true, and asserts the hook-injected EXTRA.md still appears even though workspace AGENTS.md is suppressed.
…75184) agents.defaults.skipBootstrap was checked at workspace-creation time (agent-command.ts:375 -> ensureBootstrapFiles) but the runtime injection path resolveBootstrapFilesForRun loaded and injected the workspace bootstrap files (AGENTS.md, SOUL.md, TOOLS.md, etc.) unconditionally. Result: setting skipBootstrap: true was a no-op for the system prompt — the systemPromptReport still showed all bootstrap files injected with their full per-file content. Add an early return in resolveBootstrapFilesForRun when config.agents.defaults.skipBootstrap is true, so configured opt-outs also stop the injection path. Workspace creation behavior is unchanged (the existing ensureBootstrapFiles guard still fires). Closes openclaw#75184
…for existing workspace files Codex review on PR openclaw#75217 noted that the runtime resolver guard correctly honors agents.defaults.skipBootstrap, but the public docs at docs/gateway/config-agents.md still described it as workspace-creation-only, and the diff did not include a regression proving `contextFiles` / `injectedWorkspaceFiles` stay empty when existing workspace files are present and skipBootstrap is true. Align the public contract with the new runtime behavior: - docs/gateway/config-agents.md now describes both effects of skipBootstrap (creation + runtime injection) and points users at `contextInjection: 'never'` if they want to keep files on disk but skip injection only. - src/config/types.agent-defaults.ts JSDoc on `skipBootstrap` mirrors the doc wording so editor hover and SDK consumers see the same contract. Add a regression in src/agents/bootstrap-files.test.ts that exercises the exact failure mode the issue described: write AGENTS.md and SOUL.md into the workspace, then call resolveBootstrapFilesForRun and resolveBootstrapContextForRun with skipBootstrap=true and assert both return empty results. A second case sets skipBootstrap=false / unset and asserts AGENTS.md is still resolved, so the guard does not regress the default path. Refs openclaw#75184
…enabled Codex follow-up on PR openclaw#75217 noted: the early return when agents.defaults.skipBootstrap was true bypassed applyBootstrapHookOverrides entirely, so agent:bootstrap hooks (e.g. the bundled bootstrap-extra-files handler in src/hooks/bundled/bootstrap-extra-files/handler.ts) never ran when the flag was set. That broke installations that opt out of default workspace bootstrap files but still rely on hook-injected context. skipBootstrap is meant to suppress only the WORKSPACE bootstrap files — hooks should still run. Skip the workspace file load when the flag is set and feed an empty file list into applyBootstrapHookOverrides; hooks can then return their own files which we sanitize and return like any other bootstrap result. Add a regression test that registers an agent:bootstrap hook, sets skipBootstrap to true, and asserts the hook-injected EXTRA.md still appears even though workspace AGENTS.md is suppressed.
…ype portability CI check-test-types flagged the new regression test for comparing WorkspaceBootstrapFile.name (a typed union of canonical bootstrap names) against the literal 'EXTRA.md' which is not in the union. Hooks are allowed to inject arbitrary file names, so compare via String() to keep the assertion type-portable without binding the test to the union shape.
230d7a3 to
c9774b1
Compare
Lint flagged String(file.name) as 'type conversion does not change the type or value'. Widen via .map((f) => f.name): string[] for the .includes check, and use file.name as string for the .find predicate.
martingarramon
left a comment
There was a problem hiding this comment.
The short-circuit before the workspace load while keeping applyBootstrapHookOverrides in the path is the right fix for the codex-bot follow-up about hook bypass, and the second test (hook-injected EXTRA.md survives skipBootstrap: true) locks that contract concretely.
One Q + a nit:
Q: bootstrapFilesToSkip interaction. When both skipBootstrap: true and bootstrapFilesToSkip: ["AGENTS.md"] are set, bootstrapFilesToSkip is ignored — skipBootstrap short-circuits the workspace load at src/agents/bootstrap-files.ts:248 before bootstrapFilesToSkip is evaluated. The behavior is internally consistent, but the AgentDefaultsConfig JSDoc and the docs page don't mention this layering. Please add a one-liner so users who set both knobs aren't surprised that their selective skiplist is silently ignored.
Nit: test comment at src/agents/bootstrap-files.test.ts:148 cites agent-command.ts:373 for ensureBootstrapFiles: !skipBootstrap. This line number is already stale — agent-command.ts:392 on current upstream/main. Either drop the line number or pin via a symbol-name reference.
LGTM otherwise.
Summary
agents.defaults.skipBootstrap: truewas advertised as a way to skip workspace bootstrap content, but it was a no-op for the runtime system-prompt injection.systemPromptReportstill showed AGENTS.md, SOUL.md, TOOLS.md, IDENTITY.md, USER.md, HEARTBEAT.md, BOOTSTRAP.md injected with their full per-file content.agent-command.ts:375 -> ensureBootstrapFiles: !agentCfg?.skipBootstrap) but the runtime injection pathresolveBootstrapFilesForRun(andresolveBootstrapContextForRunwhich wraps it) loaded the workspace bootstrap files unconditionally. So files created during a previous bootstrap kept being injected even after the operator set the flag.resolveBootstrapFilesForRunwhenconfig.agents.defaults.skipBootstrap === true. Empty bootstrap files → empty contextFiles → no injection. Workspace-creation behavior unchanged.Linked Issue
agents.defaults.skipBootstrap: trueis a no-op for workspace bootstrap files #75184Test Plan
pnpm tsgo:corecleanpnpm exec oxfmt --checkcleanReal behavior proof
Test:
pnpm test src/agents/bootstrap-files.test.ts— 30 passed.The new test registers an
agent:bootstraphook, setsagents.defaults.skipBootstrap: true, and asserts the hook-injectedEXTRA.mdreaches the resolver output even though workspaceAGENTS.mdis suppressed. This exercises the same production code path that runs every gateway turn —resolveBootstrapFilesForRun→applyBootstrapHookOverrides— without mocking the hook runner.