oh-my-opencode 4.18.0 → 4.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +3677 -0
- package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +3154 -0
- package/.agents/skills/work-with-pr/SKILL.md +16 -37
- package/.agents/skills/work-with-pr-workspace/evals/evals.json +3 -3
- package/.opencode/skills/work-with-pr/SKILL.md +16 -37
- package/.opencode/skills/work-with-pr-workspace/evals/evals.json +3 -3
- package/bin/AGENTS.md +33 -0
- package/dist/cli/index.js +500 -158
- package/dist/cli-node/index.js +500 -158
- package/dist/hooks/anthropic-context-window-limit-recovery/empty-content-recovery-sdk.d.ts +6 -0
- package/dist/hooks/category-skill-reminder/hook.d.ts +9 -1
- package/dist/hooks/comment-checker/hook.d.ts +8 -1
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +3 -0
- package/dist/index.js +956 -702
- package/dist/plugin/messages-transform.d.ts +1 -0
- package/dist/plugin-handlers/prometheus-agent-config-builder.d.ts +2 -0
- package/dist/tui.js +43 -4
- package/package.json +16 -16
- package/packages/git-bash-mcp/dist/cli.js +81 -19
- package/packages/lsp-core/package.json +4 -0
- package/packages/lsp-core/src/index.ts +1 -0
- package/packages/lsp-core/src/lsp/cleanup-errors.test.ts +18 -0
- package/packages/lsp-core/src/lsp/cleanup-errors.ts +12 -3
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +261 -0
- package/packages/lsp-core/src/lsp/client-wrapper.test.ts +63 -0
- package/packages/lsp-core/src/lsp/client-wrapper.ts +35 -5
- package/packages/lsp-core/src/lsp/client.ts +262 -80
- package/packages/lsp-core/src/lsp/config-loader.ts +5 -17
- package/packages/lsp-core/src/lsp/connection.ts +12 -6
- package/packages/lsp-core/src/lsp/directory-diagnostics.test.ts +221 -0
- package/packages/lsp-core/src/lsp/directory-diagnostics.ts +61 -28
- package/packages/lsp-core/src/lsp/errors.ts +11 -0
- package/packages/lsp-core/src/lsp/fixtures/diagnostics-freshness-contract-probe.ts +283 -0
- package/packages/lsp-core/src/lsp/fixtures/workspace-edit-contract-probe.ts +196 -0
- package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +215 -0
- package/packages/lsp-core/src/lsp/formatters.ts +3 -0
- package/packages/lsp-core/src/lsp/json-rpc-connection-cancellation.test.ts +97 -0
- package/packages/lsp-core/src/lsp/json-rpc-connection.ts +73 -5
- package/packages/lsp-core/src/lsp/server-install-state.ts +3 -6
- package/packages/lsp-core/src/lsp/transport-protocol.ts +52 -0
- package/packages/lsp-core/src/lsp/transport.ts +96 -70
- package/packages/lsp-core/src/lsp/workspace-apply-edit-failure.ts +19 -0
- package/packages/lsp-core/src/lsp/workspace-apply-edit-lease.integration.test.ts +214 -0
- package/packages/lsp-core/src/lsp/workspace-apply-edit-sync.integration.test.ts +113 -0
- package/packages/lsp-core/src/lsp/workspace-apply-edit-test-support.ts +163 -0
- package/packages/lsp-core/src/lsp/workspace-apply-edit.integration.test.ts +163 -0
- package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +67 -0
- package/packages/lsp-core/src/lsp/workspace-document-state.ts +368 -0
- package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +113 -0
- package/packages/lsp-core/src/lsp/workspace-edit-commit.test.ts +140 -0
- package/packages/lsp-core/src/lsp/workspace-edit-commit.ts +220 -0
- package/packages/lsp-core/src/lsp/workspace-edit-contract-evidence.test.ts +56 -0
- package/packages/lsp-core/src/lsp/workspace-edit-contract-evidence.ts +30 -0
- package/packages/lsp-core/src/lsp/workspace-edit-fingerprint.ts +44 -0
- package/packages/lsp-core/src/lsp/workspace-edit-options.test.ts +147 -0
- package/packages/lsp-core/src/lsp/workspace-edit-parse-helpers.ts +59 -0
- package/packages/lsp-core/src/lsp/workspace-edit-parser.ts +130 -0
- package/packages/lsp-core/src/lsp/workspace-edit-path.ts +98 -0
- package/packages/lsp-core/src/lsp/workspace-edit-plan-types.ts +60 -0
- package/packages/lsp-core/src/lsp/workspace-edit-plan.ts +73 -0
- package/packages/lsp-core/src/lsp/workspace-edit-prevalidation.test.ts +174 -0
- package/packages/lsp-core/src/lsp/workspace-edit-resource-parser.ts +89 -0
- package/packages/lsp-core/src/lsp/workspace-edit-simulation.ts +183 -0
- package/packages/lsp-core/src/lsp/workspace-edit-snapshot.ts +53 -0
- package/packages/lsp-core/src/lsp/workspace-edit-text.ts +125 -0
- package/packages/lsp-core/src/lsp/workspace-edit-types.ts +121 -0
- package/packages/lsp-core/src/lsp/workspace-edit.characterization.test.ts +95 -0
- package/packages/lsp-core/src/lsp/workspace-edit.ts +49 -200
- package/packages/lsp-core/src/lsp/workspace-mutation-controller.ts +182 -0
- package/packages/lsp-core/src/mcp.ts +18 -7
- package/packages/lsp-core/src/missing-dependency-result.test.ts +105 -0
- package/packages/lsp-core/src/missing-dependency-result.ts +57 -0
- package/packages/lsp-core/src/post-edit/index.ts +1 -0
- package/packages/lsp-core/src/post-edit/orchestration.test.ts +157 -0
- package/packages/lsp-core/src/post-edit/orchestration.ts +178 -0
- package/packages/lsp-core/src/request-context.test.ts +171 -0
- package/packages/lsp-core/src/request-context.ts +222 -9
- package/packages/lsp-core/src/tool-surface.test.ts +4 -1
- package/packages/lsp-core/src/tools/diagnostics.ts +32 -13
- package/packages/lsp-core/src/tools/navigation.ts +12 -12
- package/packages/lsp-core/src/tools/rename.ts +10 -15
- package/packages/lsp-core/src/tools/symbols.ts +11 -11
- package/packages/lsp-core/src/tools/types.ts +2 -1
- package/packages/lsp-daemon/dist/cli.js +3330 -764
- package/packages/lsp-daemon/dist/client.d.ts +105 -0
- package/packages/lsp-daemon/dist/client.js +5995 -0
- package/packages/lsp-daemon/dist/daemon-client.d.ts +12 -7
- package/packages/lsp-daemon/dist/daemon-client.js +139 -32
- package/packages/lsp-daemon/dist/daemon-server.d.ts +1 -0
- package/packages/lsp-daemon/dist/daemon-server.js +40 -15
- package/packages/lsp-daemon/dist/ensure-daemon.d.ts +10 -8
- package/packages/lsp-daemon/dist/ensure-daemon.js +135 -51
- package/packages/lsp-daemon/dist/index.d.ts +2 -2
- package/packages/lsp-daemon/dist/index.js +3093 -786
- package/packages/lsp-daemon/dist/ipc-protocol.d.ts +46 -0
- package/packages/lsp-daemon/dist/ipc-protocol.js +187 -0
- package/packages/lsp-daemon/dist/lock.js +14 -4
- package/packages/lsp-daemon/dist/ownership.d.ts +49 -0
- package/packages/lsp-daemon/dist/ownership.js +168 -0
- package/packages/lsp-daemon/dist/paths.d.ts +33 -9
- package/packages/lsp-daemon/dist/paths.js +72 -33
- package/packages/lsp-daemon/dist/proxy.d.ts +5 -0
- package/packages/lsp-daemon/dist/proxy.js +123 -16
- package/packages/lsp-daemon/dist/request-routing.d.ts +7 -2
- package/packages/lsp-daemon/dist/request-routing.js +71 -22
- package/packages/lsp-daemon/dist/run-daemon.js +9 -2
- package/packages/lsp-daemon/dist/runtime-contract.d.ts +21 -0
- package/packages/lsp-daemon/dist/runtime-contract.js +58 -0
- package/packages/lsp-daemon/dist/socket-jsonrpc.js +6 -1
- package/packages/lsp-daemon/package.json +12 -3
- package/packages/lsp-tools-mcp/dist/cli.js +2189 -454
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +1741 -148
- package/packages/lsp-tools-mcp/dist/mcp.js +2206 -471
- package/packages/lsp-tools-mcp/dist/request-context.js +176 -6
- package/packages/lsp-tools-mcp/dist/tools.js +2119 -447
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/.mcp.json +2 -1
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +100 -28
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +100 -28
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +21 -9
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +35 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +69 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +57 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/.mcp.json +2 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +55 -0
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +3033 -936
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.js +0 -4
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.d.ts +5 -2
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.js +41 -62
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.d.ts +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +24 -15
- package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.d.ts +3 -7
- package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.js +23 -49
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +3 -2
- package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-daemon.mjs +31 -1
- package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-daemon.test.mjs +76 -0
- package/packages/omo-codex/plugin/components/lsp/scripts/build-runtime.mjs +201 -0
- package/packages/omo-codex/plugin/components/lsp/scripts/build-runtime.test.mjs +55 -0
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook-cli.ts +0 -4
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +49 -71
- package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +26 -15
- package/packages/omo-codex/plugin/components/lsp/src/lsp-session-state.ts +26 -64
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +16 -17
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +30 -4
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +20 -5
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.5.md +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +5 -3
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/README.md +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +3 -3
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +15 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +20 -0
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +50 -33
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +50 -33
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +50 -33
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +3 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +5 -6
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +6 -5
- package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +5 -6
- package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +2 -2
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +26 -14
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +2 -3
- package/packages/omo-codex/plugin/scripts/build-components.mjs +13 -1
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +9 -1
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +7 -0
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +2 -1
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +50 -33
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +6 -5
- package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +8 -0
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +128 -15
- package/packages/omo-codex/plugin/test/install-time-build-runtime.test.mjs +10 -0
- package/packages/omo-codex/plugin/test/lsp-prebuild-layouts.test.mjs +2 -0
- package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +7 -0
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +34 -3
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +328 -63
|
@@ -23,7 +23,7 @@ This skill is intentionally compact. The full workflow lives in `references/full
|
|
|
23
23
|
- After any compaction or context loss, re-read brief + goals + ledger FIRST plus `omo ulw-loop status --json`, then resume; never re-plan from scratch.
|
|
24
24
|
- If `omo ulw-loop create-goals` says the existing aggregate is already complete, start unrelated new work with a fresh `--session-id <new-id>` instead of steering or forcing the completed default state. Use `--force` only to intentionally overwrite completed evidence.
|
|
25
25
|
- Every success criterion needs observable evidence from a real surface: a channel (terminal/TUI via the xterm.js web terminal, HTTP, browser, computer-use) or, for CLI- or data-shaped criteria, an auxiliary surface (CLI stdout, DB diff, parsed config dump).
|
|
26
|
-
- Evidence is bound to
|
|
26
|
+
- Evidence is bound to the tree it was captured at (`git rev-parse --short "HEAD^{tree}"`); it goes stale only when tracked content changes — a rebase or amend that keeps the tree identical keeps it valid. When the tree differs, re-run at the current HEAD and re-record, never relabel or regenerate. Record only after cleanup receipts exist.
|
|
27
27
|
- Delegate code edits, test writes, fixes, and QA execution to right-sized Codex subagents when the workflow requires it.
|
|
28
28
|
- Every `spawn_agent` message starts with `TASK:`, then names `DELIVERABLE`, `SCOPE`, and `VERIFY`; put role and specialty instructions inside `message`; use `fork_turns: "none"` (v1: `fork_context: false`) unless full history is truly required.
|
|
29
29
|
- Plan and reviewer agents may run for a long time; spawn them in the background and keep doing independent root work. Between `wait_agent` calls, back off — double the timeout up to ~5 minutes — instead of spinning short cycles.
|
|
@@ -165,9 +165,9 @@ Loop per goal. Cap at 5 cycles per goal. Cap identical same-criterion failures a
|
|
|
165
165
|
5. EXECUTE-AS-SCENARIO: ACTUALLY run the Manual-QA scenario the criterion named (channel table above). Run it yourself for the orchestrator check; for heavier flows dispatch a dedicated QA execution worker (`lazycodex-worker-medium` by default; `lazycodex-worker-high` when the QA flow itself is hard) whose ONLY job is to drive the channel and write the artifact to the named evidence path. If the scenario FAILS, respawn the implementing worker with the captured failure — do not hand-patch around it.
|
|
166
166
|
6. CAPTURE: collect the observable artifact path: transcript, stdout, screenshot, assertion, status+body, diff, or parsed dump. No artifact written at the evidence path — not done; record BLOCKED and respawn QA.
|
|
167
167
|
7. CLEAN (PAIRED, NEVER SKIP): tear down every runtime artifact step 5 spawned BEFORE recording — server PIDs (`kill`, verify `kill -0` fails), `tmux` sessions (`tmux kill-session -t ulw-qa-<criterion>`; confirm `tmux ls`), browser / Playwright contexts (`.close()`), containers (`docker rm -f`), bound ports (`lsof -i :<port>` empty), temp sockets / files / dirs (`rm -rf` the `mktemp` paths), QA-only env vars, AND close every finished worker (v1 `close_agent`; on V2 finished workers end on their own — `interrupt_agent` any still running). Register each teardown as its own todo the moment the QA spawns the resource (scripts, tmux assets, browsers / agent-browser sessions, PIDs, ports) so none is forgotten. Embed a one-line cleanup receipt in the evidence string, e.g. `cleanup: killed 12345; tmux kill-session ulw-qa-foo; rm -rf /tmp/ulw.aB12cD; interrupt_agent w-3`. Missing receipt → record BLOCKED, not PASS.
|
|
168
|
-
8. RECORD one result immediately from the artifact you just wrote — never from memory or a later turn — stamping the capture
|
|
169
|
-
- PASS: `omo ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status pass --evidence "<observable>
|
|
170
|
-
- FAIL: `omo ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status fail --evidence "<observable>
|
|
168
|
+
8. RECORD one result immediately from the artifact you just wrote — never from memory or a later turn — stamping the capture tree `$(git rev-parse --short "HEAD^{tree}")` into the evidence:
|
|
169
|
+
- PASS: `omo ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status pass --evidence "<observable> @tree:<short-tree> | <cleanup receipt>" --json`
|
|
170
|
+
- FAIL: `omo ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status fail --evidence "<observable> @tree:<short-tree> | <cleanup receipt>" --notes "<diagnosis>" --json`
|
|
171
171
|
- BLOCKED: `omo ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status blocked --evidence "<observable>" --notes "<safety/blocker/leftover-state>" --json`
|
|
172
172
|
9. If actual does not match expected, diagnose, respawn the right-sized worker with the failure context to fix minimally, and rerun the SAME criterion (including a fresh cleanup).
|
|
173
173
|
10. After 3 same-criterion failures, exit the goal with diagnosis.
|
|
@@ -184,9 +184,10 @@ Loop per goal. Cap at 5 cycles per goal. Cap identical same-criterion failures a
|
|
|
184
184
|
## Final Quality Gate
|
|
185
185
|
Trigger only for the final aggregate goal after every criterion in every goal is `pass`.
|
|
186
186
|
1. Run targeted verification for changed behavior.
|
|
187
|
-
2. FREEZE first — no more edits or rebases. At the frozen
|
|
187
|
+
2. FREEZE first — no more edits or rebases. At the frozen HEAD, re-run Manual-QA for any PASS criterion whose stamped tree differs from `git rev-parse --short "HEAD^{tree}"`, so every criterion is proven on the frozen tree; each artifact exists and is non-empty.
|
|
188
188
|
3a. Spawn lazycodex-code-reviewer and lazycodex-qa-executor in parallel (`fork_context: false` on v1; `fork_turns: "none"` on v2) with brief, goals, desired outcome, diff, evidence; wait for BOTH and confirm their report artifacts exist on disk.
|
|
189
189
|
3b. Only then spawn lazycodex-gate-reviewer with those artifact paths.
|
|
190
|
+
3c. The gate's approval binds to the frozen tree and full commit SHA and covers its three lanes — code quality, hands-on QA, and goal verification. Immediately append one durable `.omo/ulw-loop/ledger.jsonl` record per passing lane with the lane name, full SHA, verdict, and report artifact/source. Before reuse after continuation or compaction, re-read the ledger and require the exact lane/SHA pair; memory or an unstamped report is not coverage. A later rebase or amend that keeps the tree identical still has a new SHA and needs fresh lane stamps; changed content needs fresh review of the delta.
|
|
190
191
|
4. Treat timeout, missing deliverable, ack-only, `BLOCKED:`, or inconclusive review as a blocker. Any fix restarts the freeze at the new HEAD: re-run ONLY the proofs it invalidated and stamp the fresh output — never regenerate all evidence or relabel stale output to HEAD — re-review the delta at most TWICE; then record-review-blockers (step 5) and surface to the user.
|
|
191
192
|
5. If review remains blocked, run `omo ulw-loop record-review-blockers --goal-id <id> --title "<...>" --objective "<...>" --evidence "<review findings>" --codex-goal-json <snapshot> --json`.
|
|
192
193
|
6. If clean, checkpoint final completion:
|
|
@@ -224,7 +225,7 @@ Structured prompt directives accepted: `OMO_ULW_LOOP_STEER: { ... }`, `omo.ulw-l
|
|
|
224
225
|
## Constraints
|
|
225
226
|
1. NEVER call `update_goal` mid-aggregate; only on final story after the quality gate passes.
|
|
226
227
|
2. NEVER call `create_goal` when `get_goal` shows a different active goal.
|
|
227
|
-
3. Evidence is bound to the
|
|
228
|
+
3. Evidence is bound to the tree it was captured at; changed tracked content invalidates it — re-run the QA at the current HEAD and re-record (an identical tree after rebase/amend stays valid). NEVER mark PASS from memory, and NEVER relabel, pin, refresh, or regenerate prior output to a moved HEAD.
|
|
228
229
|
4. NEVER bypass the criteria gate: non-final aggregate completion requires all essential criteria; final aggregate completion requires all criteria across the whole plan.
|
|
229
230
|
5. Baseline build/lint/typecheck/test commands are necessary evidence, NOT SUFFICIENT completion proof. Criteria coverage with observable evidence is the gate.
|
|
230
231
|
6. Treat `.omo/ulw-loop/ledger.jsonl` as the durable audit trail; checkpoint after every success or failure.
|
|
@@ -36,3 +36,11 @@ test("#given omo-codex package build script #when inspected #then delegates to t
|
|
|
36
36
|
// then
|
|
37
37
|
assert.equal(buildPluginScript, "bun run --cwd plugin build");
|
|
38
38
|
});
|
|
39
|
+
|
|
40
|
+
test("#given a component-owned runtime manifest #when aggregate component build script is inspected #then it preserves bundled bytes", async () => {
|
|
41
|
+
const buildScript = await readFile(join(root, "scripts", "build-components.mjs"), "utf8");
|
|
42
|
+
|
|
43
|
+
assert.match(buildScript, /hasComponentOwnedBundle/u);
|
|
44
|
+
assert.match(buildScript, /"dist", "\.omo-runtime-manifest\.json"/u);
|
|
45
|
+
assert.match(buildScript, /if \(await hasComponentOwnedBundle\(task\.componentPath\)\) return/u);
|
|
46
|
+
});
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
chmodSync,
|
|
4
|
+
cpSync,
|
|
5
|
+
existsSync,
|
|
6
|
+
mkdirSync,
|
|
7
|
+
mkdtempSync,
|
|
8
|
+
readFileSync,
|
|
9
|
+
readdirSync,
|
|
10
|
+
rmSync,
|
|
11
|
+
writeFileSync,
|
|
12
|
+
} from "node:fs";
|
|
3
13
|
import { readFile } from "node:fs/promises";
|
|
4
14
|
import { tmpdir } from "node:os";
|
|
5
15
|
import { join } from "node:path";
|
|
@@ -23,6 +33,7 @@ const HOOK_EVENTS_BY_COMPONENT = {
|
|
|
23
33
|
};
|
|
24
34
|
const MCP_ONLY_COMPONENTS = new Set(["codegraph"]);
|
|
25
35
|
const HOOK_CLI_TEST_TIMEOUT_MS = 45_000;
|
|
36
|
+
const DAEMON_EXIT_TIMEOUT_MS = 5_000;
|
|
26
37
|
|
|
27
38
|
test("#given required component CLI contracts #when workspaces are inspected #then every contract component is covered", async () => {
|
|
28
39
|
// given
|
|
@@ -125,29 +136,84 @@ test("#given representative component hook payloads #when executed through dist
|
|
|
125
136
|
}
|
|
126
137
|
});
|
|
127
138
|
|
|
128
|
-
test("#given bundled LSP hook CLI in installed layout #when diagnostics run #then it spawns sibling daemon target", () => {
|
|
139
|
+
test("#given bundled LSP hook CLI in installed layout #when diagnostics run #then it spawns sibling daemon target", async () => {
|
|
129
140
|
const tempRoot = mkdtempSync(join(tmpdir(), "omo-codex-lsp-installed-"));
|
|
130
141
|
try {
|
|
131
142
|
const lspDist = join(tempRoot, "components", "lsp", "dist");
|
|
132
143
|
const daemonDist = join(tempRoot, "components", "lsp-daemon", "dist");
|
|
133
144
|
const daemonDir = join(tempRoot, "daemon");
|
|
134
|
-
const invocationLog = join(tempRoot, "fake-daemon-invocations.jsonl");
|
|
135
145
|
mkdirSync(lspDist, { recursive: true });
|
|
136
146
|
mkdirSync(daemonDist, { recursive: true });
|
|
137
147
|
mkdirSync(join(tempRoot, "src"), { recursive: true });
|
|
138
148
|
writeFileSync(join(tempRoot, "package.json"), JSON.stringify({ type: "module" }));
|
|
139
149
|
writeFileSync(join(lspDist, "cli.js"), readFileSync(componentCliPath("lsp"), "utf8"));
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
150
|
+
cpSync(join(root, "..", "..", "lsp-daemon", "dist"), daemonDist, { recursive: true });
|
|
151
|
+
const editedFile = join(tempRoot, "src", "broken.ts");
|
|
152
|
+
const scenarioPath = join(tempRoot, "scenario.json");
|
|
153
|
+
const eventsPath = join(tempRoot, "lsp-events.jsonl");
|
|
154
|
+
const codexHome = join(tempRoot, "codex-home");
|
|
155
|
+
mkdirSync(codexHome, { recursive: true });
|
|
156
|
+
writeFileSync(editedFile, "const value: string = 1;\n");
|
|
157
|
+
writeFileSync(eventsPath, "");
|
|
158
|
+
writeFileSync(
|
|
159
|
+
scenarioPath,
|
|
160
|
+
JSON.stringify({
|
|
161
|
+
publishDiagnostics: [
|
|
162
|
+
{
|
|
163
|
+
trigger: "didOpen",
|
|
164
|
+
version: 1,
|
|
165
|
+
diagnostics: [
|
|
166
|
+
{
|
|
167
|
+
range: { start: { line: 0, character: 6 }, end: { line: 0, character: 11 } },
|
|
168
|
+
severity: 1,
|
|
169
|
+
code: "fake",
|
|
170
|
+
source: "fake",
|
|
171
|
+
message: "Missing fake symbol.",
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
diagnosticResponses: [
|
|
177
|
+
{
|
|
178
|
+
report: {
|
|
179
|
+
items: [
|
|
180
|
+
{
|
|
181
|
+
range: { start: { line: 0, character: 6 }, end: { line: 0, character: 11 } },
|
|
182
|
+
severity: 1,
|
|
183
|
+
code: "fake",
|
|
184
|
+
source: "fake",
|
|
185
|
+
message: "Missing fake symbol.",
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
}),
|
|
192
|
+
);
|
|
193
|
+
writeFileSync(
|
|
194
|
+
join(codexHome, "lsp-client.json"),
|
|
195
|
+
JSON.stringify({
|
|
196
|
+
lsp: {
|
|
197
|
+
typescript: {
|
|
198
|
+
command: [
|
|
199
|
+
process.execPath,
|
|
200
|
+
join(root, "..", "..", "lsp-core", "src", "lsp", "fixtures", "workspace-edit-server.mjs"),
|
|
201
|
+
scenarioPath,
|
|
202
|
+
eventsPath,
|
|
203
|
+
],
|
|
204
|
+
extensions: [".ts"],
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
}),
|
|
208
|
+
);
|
|
144
209
|
|
|
145
210
|
const result = spawnSync(process.execPath, [join(lspDist, "cli.js"), "hook", "post-tool-use"], {
|
|
146
211
|
cwd: tempRoot,
|
|
147
212
|
encoding: "utf8",
|
|
148
213
|
env: hookEnv(tempRoot, {
|
|
149
|
-
|
|
150
|
-
|
|
214
|
+
CODEX_HOME: codexHome,
|
|
215
|
+
OMO_LSP_DAEMON_DIR: daemonDir,
|
|
216
|
+
NODE_PATH: "",
|
|
151
217
|
}),
|
|
152
218
|
input: JSON.stringify({
|
|
153
219
|
session_id: "bundled-lsp-hook",
|
|
@@ -158,17 +224,17 @@ test("#given bundled LSP hook CLI in installed layout #when diagnostics run #the
|
|
|
158
224
|
timeout: HOOK_CLI_TEST_TIMEOUT_MS,
|
|
159
225
|
});
|
|
160
226
|
|
|
161
|
-
const
|
|
162
|
-
const failureContext = `stdout: ${result.stdout}\nstderr: ${result.stderr}\ndaemon log: ${daemonInvocations}`;
|
|
227
|
+
const failureContext = `stdout: ${result.stdout}\nstderr: ${result.stderr}`;
|
|
163
228
|
assert.equal(result.status, 0, failureContext);
|
|
164
229
|
assert.equal(result.stderr, "", failureContext);
|
|
165
230
|
assert.notEqual(result.stdout, "", failureContext);
|
|
166
231
|
const parsed = JSON.parse(result.stdout);
|
|
167
232
|
assert.equal(parsed.decision, "block");
|
|
168
|
-
assert.match(parsed.reason, /
|
|
169
|
-
assert.
|
|
170
|
-
assert.equal(existsSync(join(daemonDir, "
|
|
233
|
+
assert.match(parsed.reason, /Missing fake symbol\./);
|
|
234
|
+
assert.match(readFileSync(eventsPath, "utf8"), /textDocument\/publishDiagnostics/);
|
|
235
|
+
assert.equal(existsSync(join(daemonDir, `v${JSON.parse(readFileSync(join(daemonDist, "package.json"), "utf8")).version}`, "daemon.log")), true);
|
|
171
236
|
} finally {
|
|
237
|
+
await stopTestDaemons(join(tempRoot, "daemon"));
|
|
172
238
|
rmSync(tempRoot, { recursive: true, force: true });
|
|
173
239
|
}
|
|
174
240
|
});
|
|
@@ -336,7 +402,7 @@ function writeFakeLspDaemonCli(path) {
|
|
|
336
402
|
'import { createServer } from "node:net";',
|
|
337
403
|
"",
|
|
338
404
|
"appendFileSync(process.env.FAKE_LSP_DAEMON_LOG, `${JSON.stringify(process.argv.slice(2))}\\n`);",
|
|
339
|
-
"const baseDir = process.env.
|
|
405
|
+
"const baseDir = process.env.OMO_LSP_DAEMON_DIR;",
|
|
340
406
|
'const versionDirName = readdirSync(baseDir).find((entry) => entry.startsWith("v")) ?? "v0";',
|
|
341
407
|
"const version = versionDirName.slice(1);",
|
|
342
408
|
"const dir = join(baseDir, versionDirName);",
|
|
@@ -374,6 +440,53 @@ function writeFakeLspDaemonCli(path) {
|
|
|
374
440
|
);
|
|
375
441
|
}
|
|
376
442
|
|
|
443
|
+
async function stopTestDaemons(daemonRoot) {
|
|
444
|
+
if (!existsSync(daemonRoot)) return;
|
|
445
|
+
for (const versionDir of readdirSync(daemonRoot)) {
|
|
446
|
+
const pidPath = join(daemonRoot, versionDir, "daemon.pid");
|
|
447
|
+
if (!existsSync(pidPath)) continue;
|
|
448
|
+
const pid = Number(readFileSync(pidPath, "utf8").trim());
|
|
449
|
+
if (!Number.isInteger(pid) || pid <= 0) continue;
|
|
450
|
+
if (process.platform === "win32") {
|
|
451
|
+
const result = spawnSync("taskkill", ["/pid", String(pid), "/f", "/t"], {
|
|
452
|
+
encoding: "utf8",
|
|
453
|
+
windowsHide: true,
|
|
454
|
+
});
|
|
455
|
+
if (result.error) throw result.error;
|
|
456
|
+
if (result.status !== 0 && processIsRunning(pid)) {
|
|
457
|
+
throw new Error(
|
|
458
|
+
`taskkill failed for test daemon ${pid}: exit=${result.status} stderr=${result.stderr.trim()}`,
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
} else {
|
|
462
|
+
try {
|
|
463
|
+
process.kill(pid, "SIGTERM");
|
|
464
|
+
} catch (error) {
|
|
465
|
+
if (error instanceof Error && "code" in error && error.code === "ESRCH") continue;
|
|
466
|
+
throw error;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
await waitForProcessExit(pid);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
async function waitForProcessExit(pid) {
|
|
474
|
+
const deadline = Date.now() + DAEMON_EXIT_TIMEOUT_MS;
|
|
475
|
+
while (processIsRunning(pid)) {
|
|
476
|
+
if (Date.now() >= deadline) throw new Error(`Timed out waiting for test daemon ${pid} to exit`);
|
|
477
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function processIsRunning(pid) {
|
|
482
|
+
try {
|
|
483
|
+
process.kill(pid, 0);
|
|
484
|
+
return true;
|
|
485
|
+
} catch {
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
377
490
|
function hookEnv(tempRoot, extraEnv = {}) {
|
|
378
491
|
return {
|
|
379
492
|
...process.env,
|
|
@@ -31,3 +31,13 @@ test("#given aggregate build scripts #when inspected #then npm subprocesses reso
|
|
|
31
31
|
assert.match(installTimeBuildScripts, /shell: process\.platform === "win32"/);
|
|
32
32
|
assert.doesNotMatch(installTimeBuildScripts, /npm\.cmd/);
|
|
33
33
|
});
|
|
34
|
+
|
|
35
|
+
test("#given bundled MCP runtime builds #when a locked runtime has no node_modules #then npm ci bootstraps it before build", async () => {
|
|
36
|
+
// given
|
|
37
|
+
const buildBundledMcpRuntimesScript = await readFile(join(root, "scripts", "build-bundled-mcp-runtimes.mjs"), "utf8");
|
|
38
|
+
|
|
39
|
+
// then
|
|
40
|
+
assert.match(buildBundledMcpRuntimesScript, /package-lock\.json/);
|
|
41
|
+
assert.match(buildBundledMcpRuntimesScript, /spawnSync\("npm", \["ci"\]/);
|
|
42
|
+
assert.match(buildBundledMcpRuntimesScript, /!existsSync\(join\(runtime\.packageRoot, "node_modules"\)\)/);
|
|
43
|
+
});
|
|
@@ -64,6 +64,8 @@ test("#given the installed cache layout #when running build-lsp-daemon #then use
|
|
|
64
64
|
|
|
65
65
|
await mkdir(join(root, "components", "lsp-daemon", "dist"), { recursive: true });
|
|
66
66
|
await writeFile(join(root, "components", "lsp-daemon", "dist", "cli.js"), "");
|
|
67
|
+
await writeFile(join(root, "components", "lsp-daemon", "dist", "client.js"), "");
|
|
68
|
+
await writeFile(join(root, "components", "lsp-daemon", "dist", "client.d.ts"), "");
|
|
67
69
|
await writeFile(join(root, "components", "lsp-daemon", "dist", "index.js"), "");
|
|
68
70
|
await writeFile(join(root, "components", "lsp-daemon", "dist", "index.d.ts"), "");
|
|
69
71
|
|
|
@@ -20,4 +20,5 @@ test("#given aggregate MCP config #when inspected #then registers research MCPs
|
|
|
20
20
|
assert.equal(Object.hasOwn(mcp.mcpServers, "ast_grep"), false);
|
|
21
21
|
assert.deepEqual(mcp.mcpServers.codegraph.args, ["components/codegraph/dist/serve.js"]);
|
|
22
22
|
assert.equal(mcp.mcpServers.codegraph.required, false);
|
|
23
|
+
assert.equal(mcp.mcpServers.lsp.startup_timeout_sec, 10);
|
|
23
24
|
});
|
|
@@ -241,6 +241,9 @@ test("#given start-work skill #when synced for Codex #then the difficulty-tier d
|
|
|
241
241
|
assert.match(content, /lazycodex-worker-medium/);
|
|
242
242
|
assert.match(content, /Delegation by difficulty/);
|
|
243
243
|
assert.match(content, /Global Review and Debugging Gate/);
|
|
244
|
+
assert.match(content, /full commit SHA/);
|
|
245
|
+
assert.match(content, /re-read the ledger record/);
|
|
246
|
+
assert.match(content, /exact lane\/SHA pair/);
|
|
244
247
|
assert.doesNotMatch(content, /works the same on both surfaces/);
|
|
245
248
|
});
|
|
246
249
|
|
|
@@ -256,6 +259,10 @@ test("#given review-work skill #when some lanes do not finish #then aggregate re
|
|
|
256
259
|
assert.match(content, /Do not spin in repeated/);
|
|
257
260
|
assert.match(content, /bare REJECT\/FAIL token without findings is not a verdict/);
|
|
258
261
|
assert.match(content, /cites the violated goal criterion/);
|
|
262
|
+
assert.match(content, /append a durable task-evidence record/);
|
|
263
|
+
assert.match(content, /full commit SHA/);
|
|
264
|
+
assert.match(content, /re-read that record/);
|
|
265
|
+
assert.match(content, /exact lane\/SHA pair/);
|
|
259
266
|
assert.match(content, /Do not use `multi_agent_v1\.send_input` as an interrupt/);
|
|
260
267
|
});
|
|
261
268
|
|
|
@@ -79,7 +79,8 @@ const startWorkCodexCompletion = `When all top-level checkboxes in \`## TODOs\`
|
|
|
79
79
|
1. Run the plan's final verification commands.
|
|
80
80
|
2. Complete the **Global Review and Debugging Gate** before any completion claim, PR creation, PR handoff, branch handoff, or merge:
|
|
81
81
|
- Invoke the \`review-work\` skill with the final diff, changed files, user goal, constraints, run command, and verification evidence. All five review lanes must return PASS. A timeout, missing deliverable, ack-only child, \`BLOCKED:\`, or inconclusive lane is a gate failure, not approval.
|
|
82
|
-
-
|
|
82
|
+
- Each passing review lane binds to the exact full commit SHA it reviewed. Immediately append a durable record to \`.omo/start-work/ledger.jsonl\` with the lane name, full SHA, PASS verdict, and report artifact/source. Before same-SHA reuse after any continuation or compaction, re-read the ledger record and require the exact lane/SHA pair; memory, chat history, or an unstamped report is not coverage. New commits require fresh applicable lane coverage.
|
|
83
|
+
- Run a debugging-oriented runtime audit even when the review passes: name at least three plausible failure hypotheses for the changed surface, run the distinguishing checks against the actual artifact, and append a separate durable record with the audit name, exact full SHA, verdict, and evidence artifact/source to \`.omo/start-work/ledger.jsonl\`. Reuse it only after re-reading an exact audit/SHA match.
|
|
83
84
|
- If any review lane or debugging hypothesis fails, invoke the \`debugging\` skill, confirm root cause with runtime evidence, add the minimal failing test or reproduction, fix it, rerun the affected verification, then rerun the Global Review and Debugging Gate.
|
|
84
85
|
- Evidence hygiene is mandatory: redact or mask secrets and sensitive user data before writing \`.omo/start-work/ledger.jsonl\`, a PR body, or a handoff. Never include raw tokens, credentials, auth headers, cookies, API keys, env dumps, private logs, or PII; use concise summaries, lengths, hashes, or short non-sensitive prefixes instead.
|
|
85
86
|
- If the work includes creating, updating, or handing off a PR, refresh \`git status\` and the PR/branch state from the task-owned worktree after the gate, and include only redacted review/debugging evidence in the PR body or handoff.
|
|
@@ -91,8 +92,38 @@ const startWorkOriginalHardRule = "- No completion claim while an applicable ult
|
|
|
91
92
|
|
|
92
93
|
const startWorkCodexHardRule = "- No completion claim while an applicable ultraqa adversarial class was never probed. Each applicable class needs a captured observable result; each skipped class needs a one-line not-applicable reason in the ledger.\n- No `ORCHESTRATION COMPLETE`, final response, PR creation, PR handoff, or merge before the Global Review and Debugging Gate passes with recorded evidence.\n- No PR/branch implementation or review in the main worktree; create or use a task-owned git worktree first.\n- No unprefixed session ids in Boulder state. Codex sessions are always `codex:<session_id>`.";
|
|
93
94
|
|
|
94
|
-
const
|
|
95
|
-
|
|
95
|
+
const reviewWorkCodexGate = `
|
|
96
|
+
When \`review-work\` is used as a final implementation, PR, or \`$start-work\`
|
|
97
|
+
gate, it is blocking. A timeout, missing deliverable, ack-only response,
|
|
98
|
+
explicit \`BLOCKED:\`, or inconclusive lane is not a pass. Treat that lane as
|
|
99
|
+
failed, investigate the underlying uncertainty with the \`debugging\` skill when
|
|
100
|
+
runtime behavior may be wrong, fix with evidence, and rerun the affected lane
|
|
101
|
+
before claiming completion, creating or handing off a PR, or merging.
|
|
102
|
+
|
|
103
|
+
After each lane reaches PASS, immediately append a durable task-evidence record
|
|
104
|
+
to the active ledger with the lane name, exact full commit SHA, PASS verdict,
|
|
105
|
+
and report artifact/source. Before reusing coverage after continuation or
|
|
106
|
+
compaction, re-read that record and require the exact lane/SHA pair. Memory,
|
|
107
|
+
chat history, or an unstamped report is not coverage; a new commit requires
|
|
108
|
+
fresh applicable lane records.
|
|
109
|
+
|
|
110
|
+
A rejecting lane must name its blockers inline in its final message — each
|
|
111
|
+
blocker cites the violated goal criterion or requirement plus an evidence
|
|
112
|
+
pointer. A bare REJECT/FAIL token without findings is not a verdict; treat it
|
|
113
|
+
as an inconclusive lane (one bounded respawn, then record it inconclusive with
|
|
114
|
+
that reason).
|
|
115
|
+
|
|
116
|
+
When reviewing a PR or branch, collect diff, file contents, and verification
|
|
117
|
+
results from a dedicated review worktree attached to that branch. Never
|
|
118
|
+
checkout, test, or edit the review branch in the main worktree.
|
|
119
|
+
|
|
120
|
+
Review evidence must be safe to share. Redact or mask secrets and sensitive
|
|
121
|
+
user data before including evidence in logs, PR bodies, or handoffs. Never
|
|
122
|
+
include raw tokens, credentials, auth headers, cookies, API keys, env dumps,
|
|
123
|
+
private logs, or PII; summarize with lengths, hashes, and short non-sensitive
|
|
124
|
+
prefixes when identity is needed.
|
|
125
|
+
`;
|
|
126
|
+
const reviewWorkCodexGatePattern = new RegExp(reviewWorkCodexGate.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
96
127
|
|
|
97
128
|
export function removeCodexSkillOverlays(skillName, content) {
|
|
98
129
|
if (skillName === "ulw-research") {
|