Repository navigation
fix(OMN-20700): a developer workspace finds its runtime config without the private sibling repo - #4754
Conversation
…e file is staged pre-commit runs scripts/validation/check_no_infra_inmemory_import.sh with pass_filenames and files ^src/omnibase_infra/.*\.py$. With one file operand, grep -rnE prints no file name, so each hit reads "131:from omnibase_infra.event_bus.event_bus_inmemory import EventBusInmemory" and the path taken from the hit is "131", which matches no ALLOWLIST entry. Staging only src/omnibase_infra/runtime/service_kernel.py, an ALLOWLIST entry, failed the hook and blocked the commit. The change is grep -H, which prints the file name for every hit. Two tests added to tests/unit/scripts/validation/test_check_no_infra_inmemory_import.py: a single staged allowlisted file passes; a single staged non-allowlisted file fails and is named. The previous script exits 1 on the first case; the changed script exits 0. 14 tests pass.
…t the private sibling repo Before, workspace_runtime_config_root() used $ONEX_WORKSPACE_CONFIG_ROOT, else <workspace>/../omnibase_internal. omnibase_internal is a private repository that the public onboarding never clones. The public onboarding script (omniclaude lab-onboarding.sh, phase 2) writes the developer config to <workspace>/.onex/workspace-config and exports ONEX_WORKSPACE_CONFIG_ROOT only in its own process and the shell profile it writes. A shell without that export still binds the workspace root, because the onex wrapper derives OMNIBASE_PATH, so onex delegate was refused. Now, with the variable unset, the sibling ../omnibase_internal is used when it is a directory (registry workspaces unchanged); otherwise <workspace>/.onex/workspace-config when it is a directory. A bound root with no config anywhere is still refused (OMN-19193), now as WorkspaceRuntimeConfigMissingError, a ProtocolConfigurationError subclass, whose message names ONEX_WORKSPACE_CONFIG_ROOT, the developer config path and phase 2 of lab-onboarding.sh, and keeps --bus inmemory. New test file tests/unit/cli/test_omn20700_developer_workspace_config_owner.py: 5 tests; 2 failed before the change and 3 passed; all 5 pass after.
…pace, end to end
Adds tests/integration/cli/test_omn20700_developer_workspace_default_cli.py with 2 tests.
They use click's delegate_command with OMNIBASE_PATH bound and
ONEX_WORKSPACE_CONFIG_ROOT unset, no sibling omnibase_internal, and no --bus,
--lane, --locus or --omnibase-path. Test 1: with the config lab-onboarding.sh
phase 2 writes at .onex/workspace-config, the run exits 0 and the captured
dispatch has backend_overrides {"event_bus": "inmemory"}. Test 2: with no
config anywhere, the run is refused, the output names ONEX_WORKSPACE_CONFIG_ROOT,
lab-onboarding.sh, .onex/workspace-config and --bus inmemory, and nothing is
dispatched. Against an export of origin/dev 59e23ec both tests failed; on this
branch both pass. The Integration Test Coverage check requires a
tests/integration file in a PR that changes src.
|
Lab: head=c8d8358a33120b7ad028190a4e9efd7b85527b18 host=h202 lane=onboard-20700-2155 — Fresh HOME on lab host h202 with no |
…13366) * evidence(OMN-20700): author OCC companion for OmniNode-ai/omnibase_infra#4754 OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head c8d8358a33120b7ad028190a4e9efd7b85527b18. * evidence(OMN-20700): self-bind OCC#13366 + rebind contract_sha256 --------- Co-authored-by: omnimarket-bot <bot@omninode.ai>
There was a problem hiding this comment.
Hostile Reviewer — adversarial findings (OMN-17492)
Models succeeded: qwen3-review, gpt-oss-review
Models failed: none
New finding threads: 0
Deduped (already posted on this PR): 0
Below quorum (one model only, reported not threaded): 7
Nit-level findings suppressed: 1
The model is the FINDER, never the gate: merge is gated only by the
deterministic Hostile Review Thread Gate, which blocks while
hostile-reviewer threads are unresolved. Resolve each thread after
addressing (or rejecting, with a reply) its finding.
Below quorum: 7 finding(s) raised by one model only (OMN-18479)
These are reported and NOT dropped, but they get no thread and do not block: a single model's finding no other model reproduced is not evidence enough to stop a merge. Read them; act on them if they are right.
- [CRITICAL]
src/omnibase_infra/runtime/service_kernel.py(gpt-oss-review) — Incorrect error type raised for missing config in resolve_embedded_runtime_config | The functionresolve_embedded_runtime_configraisesWorkspaceRuntimeConfigMissingErrorwhen no configuration is - [MAJOR]
scripts/validation/check_no_infra_inmemory_import.sh:120(qwen3-review) — grep -H flag is redundant with -r and may break on some grep implementations | The diff adds -H to grep -rnE. The -H flag forces filename prefixing, but -r (recursive) already implies -H on GNU grep a - [MAJOR]
src/omnibase_infra/runtime/service_kernel.py:1348-1355(qwen3-review) — workspace_runtime_config_root follows symlinks via .resolve() without validation | The new resolution logic calls .resolve() on sibling and developer paths. Path.resolve() follows symlinks. If an atta - [MAJOR]
src/omnibase_infra/runtime/service_kernel.py:1495-1505(qwen3-review) — Missing config error message duplicates resolution logic instead of reusing workspace_runtime_config_root | In resolve_embedded_runtime_config, when no config is found, the code manually recomputes si - [MAJOR]
tests/integration/cli/test_omn20700_developer_workspace_default_cli.py:78(qwen3-review) — Integration test monkeypatches Path.home as a classmethod, which is fragile and may break under pytest-asyncio or other fixtures | The captured_dispatch fixture monkeypatches Path.home with a classmet - [MINOR]
src/omnibase_infra/runtime/service_kernel.py:1348-1350(qwen3-review) — No test for the case where ONEX_WORKSPACE_CONFIG_ROOT points to a non-existent directory | The resolution logic in workspace_runtime_config_root does not check if the configured path exists. If ONEX_W - [MINOR]
src/omnibase_infra/runtime/service_kernel.py:260-263(qwen3-review) — DEVELOPER_WORKSPACE_CONFIG_RELATIVE_PATH is a module-level constant but its semantics are tied to the onboarding script | The constant DEVELOPER_WORKSPACE_CONFIG_RELATIVE_PATH = Path(".onex") / "works
✅ Hostile Reviewer — REVIEWEDCritical findings: 1
Semantics (OMN-17492 — the model finds, thread resolution gates)
Powered by omniintelligence.review_pairing.cli_review — multi-model adversarial review: qwen3-review (Qwen3.8-27B), gpt-oss-review (gpt-oss-120b) (OMN-8468/OMN-8524/OMN-17492) |
There was a problem hiding this comment.
Hostile Reviewer — adversarial findings (OMN-17492)
Models succeeded: qwen3-review, gpt-oss-review
Models failed: none
New finding threads: 0
Deduped (already posted on this PR): 0
Below quorum (one model only, reported not threaded): 6
Nit-level findings suppressed: 1
The model is the FINDER, never the gate: merge is gated only by the
deterministic Hostile Review Thread Gate, which blocks while
hostile-reviewer threads are unresolved. Resolve each thread after
addressing (or rejecting, with a reply) its finding.
Below quorum: 6 finding(s) raised by one model only (OMN-18479)
These are reported and NOT dropped, but they get no thread and do not block: a single model's finding no other model reproduced is not evidence enough to stop a merge. Read them; act on them if they are right.
- [CRITICAL]
src/omnibase_infra/runtime/service_kernel.py(gpt-oss-review) — Ambiguous error message for missing config owner | The error message generated when no workspace config is found concatenates details about the sibling operator repository and the developer config pat - [MAJOR]
scripts/validation/check_no_infra_inmemory_import.sh(qwen3-review) — grep -H flag is redundant and the comment misstates its purpose | The diff adds-Hto agrep -rnEinvocation and comments that it 'preserves filename headers for a single staged file operand.' Thi - [MAJOR]
src/omnibase_infra/runtime/service_kernel.py(qwen3-review) — Unsanitized environment variable used in path resolution | Theworkspace_runtime_config_rootfunction readsONEX_WORKSPACE_CONFIG_ROOTfrom the environment and passes it directly to `Path(configur - [MAJOR]
src/omnibase_infra/runtime/service_kernel.py(qwen3-review) — Inconsistent path resolution in error message construction | Inresolve_embedded_runtime_config, the error message construction computessiblinganddeveloper_configpaths using `workspace_root - [MINOR]
tests/unit/cli/test_omn20700_developer_workspace_config_owner.py(qwen3-review) — Test does not verify that the sibling path is not used when developer config exists | The testtest_a_fresh_developer_workspace_resolves_the_config_onboarding_wroteasserts that `"omnibase_internal" - [MINOR]
tests/unit/cli/test_omn20700_developer_workspace_config_owner.py(qwen3-review) — Missing test for ONEX_WORKSPACE_CONFIG_ROOT pointing to a non-existent path | The test suite does not cover the case whereONEX_WORKSPACE_CONFIG_ROOTis set to a path that does not exist. The `works
Summary
Ticket OMN-20700: fresh-account onboarding cannot delegate because the runtime config owner moved to a private sibling repo. Parent change omnibase_infra#4630 (OMN-19743) made onex delegate read the config owner from ONEX_WORKSPACE_CONFIG_ROOT, else
<workspace>/../omnibase_internal, and refuse otherwise (OMN-19193). omnibase_internal is private and onboarding never clones it. Ruling 2026-10-06: a new user must never need a private repo.Why
omniclaude#2565 (296be3fa) makes onboarding write
<workspace>/.onex/workspace-configand export ONEX_WORKSPACE_CONFIG_ROOT, but only in the script's own process and the shell profile it writes. The onex wrapper derives OMNIBASE_PATH itself, so a shell without the export still binds the workspace root and was refused.Changes
Commit 6dfdc23: scripts/validation/check_no_infra_inmemory_import.sh uses grep -H. With one staged file, grep printed no file name, the path read as "131", and the allowlisted src/omnibase_infra/runtime/service_kernel.py failed the pre-commit hook. Two tests added to tests/unit/scripts/validation/test_check_no_infra_inmemory_import.py; the previous script exits 1 on the single allowlisted file case and the changed script exits 0.
Commit 2f84790: workspace_runtime_config_root() order is ONEX_WORKSPACE_CONFIG_ROOT when set; the sibling ../omnibase_internal when it is a directory (registry workspaces unchanged);
<workspace>/.onex/workspace-configwhen it is a directory; otherwise the sibling path, and the caller refuses. The refusal of a bound root with no config anywhere (OMN-19193) is kept and is now WorkspaceRuntimeConfigMissingError, a ProtocolConfigurationError subclass; its message keeps every earlier sentence including --bus inmemory, and adds, when the variable is unset, the sibling path and the developer config path, then that phase 2 of lab-onboarding.sh writes that file or ONEX_WORKSPACE_CONFIG_ROOT can name the directory. New constants ENV_WORKSPACE_CONFIG_ROOT and DEVELOPER_WORKSPACE_CONFIG_RELATIVE_PATH.Code drafted by Codex (threads 01a11d86-864f-7d33-8ed3-32ca6a388575 and 01a11d90-70e2-78e0-9e84-eab93b9dbddb); the lane read the diffs and ran the tests.
Companion PR: omniclaude#2622 (ONBOARDING.md text).
Tests
Test file tests/unit/cli/test_omn20700_developer_workspace_config_owner.py, 5 tests: before the change 2 failed (fresh developer workspace resolves the onboarding config; typed refusal names the public fix) and 3 passed (registry sibling still answers; registry sibling without config still refused; the variable outranks both). After: 5 pass.
Focused suites (OMN-20700, OMN-19193, OMN-19212 unit and integration, in-memory import gate): 66 passed. tests/unit/cli plus the three service_kernel unit files: 1202 passed, 22 skipped (omnimarket not installed in that venv). ruff and mypy clean on service_kernel.py. pre-commit passed on both commits.
Fresh-walk proof (Operating Rule 24)
Fresh HOME /scratch/tmp/jonah/onb-20700-walk-20261008T220213Z/home; env -i with only HOME, USER, LOGNAME, SHELL, TERM, LANG, TMPDIR, PATH; no OMNI_HOME, OMNIBASE_PATH or ONEX_* set; GIT_CONFIG_GLOBAL=/dev/null; no git credentials.
ONBOARDING.md "Run it" commands run verbatim: curl of lab-onboarding.sh at 296be3faf32a3443adc7dbb818233bcd323c415c, then shasum -a 256 -c printed "lab-onboarding.sh: OK".
bash lab-onboarding.sh --preflight-only exited 1 at phase 0: "Linux is not macOS". The script supports macOS only, so phases 0 and 1 (Xcode tools, Homebrew) were not run; uv was linked into PATH in place of phase 1.
Phases 2 and 3 ran from the downloaded script with its functions unchanged (only the final
mainline replaced bysettle_model_key; phase2; phase3), with --provider ollama --ollama-model qwen2.5-coder:1.5b --no-containers, against the Ollama server already running on h202 at 127.0.0.1:11434 (anollamashim on PATH stood in for the Mac app, because the model was already present).Phase 2 PASSED in 18s: cloned omnibase_compat omnibase_core omnibase_spi omnibase_infra omnimarket omniclaude omnidash over HTTPS without credentials; no omnibase_internal clone; wrote
<workspace>/.onex/workspace-config/config/onex/runtime/runtime_config.yaml. omnibase_infra clone at dev head 724a6fa.Phase 3 PASSED in 44s: onex version 0.47.35; run 5349cc1d-0690-417c-be4f-5f0b2ef15a83 answered "hello", receipt status success, model qwen2.5-coder:1.5b, endpoint http://127.0.0.1:11434/v1/chat/completions.
New shell with nothing set (OMNIBASE_PATH, ONEX_WORKSPACE_CONFIG_ROOT, OMNI_HOME all unset),
onex delegate --json "Reply with exactly one word: hello"through ~/.local/bin/onex:<home>/code/omnibase_internal/config/onex/runtime/runtime_config.yaml.<workspace>/.onex/workspace-config/config/onex/runtime/runtime_config.yaml.Not covered
The walk ran on Linux, not macOS; phases 0, 1, 4, 5 and 6 were not run. Each default onex delegate in a developer workspace still logs a warning that materialisation failed, because .onex/workspace-config is not a git repository; that warning was already printed when ONEX_WORKSPACE_CONFIG_ROOT pointed at the same directory.
Evidence-Ticket: OMN-20700
Evidence-Source: OCC#13366