From 675d828077d7137f1d4ba5c3e1ec29a0a23ace97 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 30 May 2026 20:55:04 +0900 Subject: [PATCH] fix(omo-codex): avoid context-heavy agent polling --- .../plugin/components/ultrawork/directive.md | 2 ++ .../ultrawork/test/codex-hook.test.ts | 22 +++++++++++++++++++ .../ulw-loop/skills/ulw-loop/SKILL.md | 2 +- .../ulw-loop/test/package-smoke.test.ts | 14 ++++++++++++ .../omo-codex/plugin/skills/ulw-loop/SKILL.md | 2 +- .../plugin/test/sync-skills.test.mjs | 21 ++++++++++++++++++ 6 files changed, 61 insertions(+), 2 deletions(-) diff --git a/packages/omo-codex/plugin/components/ultrawork/directive.md b/packages/omo-codex/plugin/components/ultrawork/directive.md index 5ca2395c4..f5ec9a299 100644 --- a/packages/omo-codex/plugin/components/ultrawork/directive.md +++ b/packages/omo-codex/plugin/components/ultrawork/directive.md @@ -185,6 +185,8 @@ Until every success-criteria scenario PASSES with BOTH evidence pieces: Parallel-batch independent reads / searches / subagents within a step, but NEVER parallelise RED and GREEN of the same criterion. +Do not use `list_agents` as a polling or status tool in long or high-context runs; it can replay large agent status and latest-message payloads. +Track spawned agent names locally, use `wait_agent` for completion, send targeted followups only when needed, and `close_agent` after integrating each result. # Verification gate (TRIGGERED, NOT OPTIONAL) diff --git a/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts b/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts index 56126ef0a..c204cb919 100644 --- a/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +++ b/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts @@ -145,6 +145,28 @@ describe("codex ultrawork hook", () => { expect(parsed.hookSpecificOutput.additionalContext).toMatch(/4\. Computer use/); expect(parsed.hookSpecificOutput.additionalContext).toMatch(/CLEANUP \(PAIRED/); }); + + it("#given directive #when inspected #then avoids context-expensive agent polling", () => { + // given + const payload = { + hook_event_name: "UserPromptSubmit", + prompt: "please ultrawork", + }; + + // when + const output = runUserPromptSubmitHook(payload); + const parsed = parseHookOutput(output); + + // then + const directive = parsed.hookSpecificOutput.additionalContext; + expect(directive).toMatch(/list_agents/); + expect(directive).toMatch(/polling or status tool/); + expect(directive).toMatch(/replay large agent status and latest-message payloads/); + expect(directive).toMatch(/Track spawned agent names locally/); + expect(directive).toMatch(/wait_agent.*completion/); + expect(directive).toMatch(/targeted followups only when needed/); + expect(directive).toMatch(/close_agent.*after integrating each result/); + }); }); interface UserPromptSubmitHookOutput { diff --git a/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md b/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md index e2e989e49..aa0433abe 100644 --- a/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +++ b/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md @@ -40,7 +40,7 @@ Size each worker to the task — never spend `xhigh` on a one-liner, never send | External library / docs research | `librarian` | role default | role default | | Final verification audit | `codex-ultrawork-reviewer` | role default | role default | -Every worker message MUST carry: goal + exact files in scope; the baseline characterization test pinning current behavior when the task touches existing code, then the failing test / reproduction required before production code; constraints + project rules; the verification commands to run; the ONE Manual-QA channel and the exact evidence artifact to capture. Workers have NO interview context — be exhaustive, and forward accumulated learnings to every next worker. Track running workers; `wait_agent` for results, `close_agent` when done. +Every worker message MUST carry: goal + exact files in scope; the baseline characterization test pinning current behavior when the task touches existing code, then the failing test / reproduction required before production code; constraints + project rules; the verification commands to run; the ONE Manual-QA channel and the exact evidence artifact to capture. Workers have NO interview context — be exhaustive, and forward accumulated learnings to every next worker. Do not use `list_agents` as a polling or status tool in long or high-context runs; it can replay large agent status and latest-message payloads. Track spawned agent names locally, use `wait_agent` for completion, send targeted followups only when needed, and `close_agent` after integrating each result. ## Artifacts - `.omo/ulw-loop/brief.md`: original brief and durable constraints. diff --git a/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts b/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts index 995cc290d..00412b69e 100644 --- a/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +++ b/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts @@ -128,6 +128,20 @@ describe("skills/ulw-loop/SKILL.md", () => { const text = await readText("skills/ulw-loop/SKILL.md"); expect(text).toContain(".omo/ulw-loop"); }); + + it("#given long Codex runs #when worker guidance is inspected #then avoids context-expensive agent polling", async () => { + const text = await readText("skills/ulw-loop/SKILL.md"); + + expect(text).toMatch(/list_agents/); + expect(text).toMatch(/polling or status tool/); + expect(text).toMatch(/replay large agent status and latest-message payloads/); + expect(text).toMatch(/Track spawned agent names locally/); + expect(text).toMatch(/wait_agent.*completion/); + expect(text).toMatch(/targeted followups only when needed/); + expect(text).toMatch(/close_agent.*after integrating each result/); + expect(text).toContain("Every worker message MUST carry"); + expect(text).toContain("Each worker does strict TDD"); + }); }); describe("source LOC budget", () => { diff --git a/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md b/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md index e2e989e49..aa0433abe 100644 --- a/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +++ b/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md @@ -40,7 +40,7 @@ Size each worker to the task — never spend `xhigh` on a one-liner, never send | External library / docs research | `librarian` | role default | role default | | Final verification audit | `codex-ultrawork-reviewer` | role default | role default | -Every worker message MUST carry: goal + exact files in scope; the baseline characterization test pinning current behavior when the task touches existing code, then the failing test / reproduction required before production code; constraints + project rules; the verification commands to run; the ONE Manual-QA channel and the exact evidence artifact to capture. Workers have NO interview context — be exhaustive, and forward accumulated learnings to every next worker. Track running workers; `wait_agent` for results, `close_agent` when done. +Every worker message MUST carry: goal + exact files in scope; the baseline characterization test pinning current behavior when the task touches existing code, then the failing test / reproduction required before production code; constraints + project rules; the verification commands to run; the ONE Manual-QA channel and the exact evidence artifact to capture. Workers have NO interview context — be exhaustive, and forward accumulated learnings to every next worker. Do not use `list_agents` as a polling or status tool in long or high-context runs; it can replay large agent status and latest-message payloads. Track spawned agent names locally, use `wait_agent` for completion, send targeted followups only when needed, and `close_agent` after integrating each result. ## Artifacts - `.omo/ulw-loop/brief.md`: original brief and durable constraints. diff --git a/packages/omo-codex/plugin/test/sync-skills.test.mjs b/packages/omo-codex/plugin/test/sync-skills.test.mjs index 735460620..abc3818a0 100644 --- a/packages/omo-codex/plugin/test/sync-skills.test.mjs +++ b/packages/omo-codex/plugin/test/sync-skills.test.mjs @@ -152,6 +152,27 @@ test("#given synced ulw-loop skill #when Codex hint metadata is inspected #then assert.match(interfaceMetadata, /- "ulw-loop"/); }); +test("#given synced ulw-loop skill #when worker guidance is inspected #then context-hygiene guidance matches the source", async () => { + // given + const sourceSkill = await readFile(join(root, "components", "ulw-loop", "skills", "ulw-loop", "SKILL.md"), "utf8"); + const syncedSkill = await readFile(join(root, "skills", "ulw-loop", "SKILL.md"), "utf8"); + const requiredPatterns = [ + ["list_agents polling guard", /list_agents/], + ["status polling warning", /polling or status tool/], + ["large payload replay risk", /replay large agent status and latest-message payloads/], + ["local spawned-name tracking", /Track spawned agent names locally/], + ["wait_agent completion path", /wait_agent.*completion/], + ["targeted followups", /targeted followups only when needed/], + ["close_agent cleanup", /close_agent.*after integrating each result/], + ]; + + // when / then + for (const [label, pattern] of requiredPatterns) { + assert.match(sourceSkill, pattern, `source skill missing ${label}`); + assert.match(syncedSkill, pattern, `synced skill missing ${label}`); + } +}); + test("#given synced aggregate Codex skills #when they contain OpenCode orchestration examples #then Codex tool compatibility guidance is injected", async () => { // given const skillsRoot = join(root, "skills");