Skip to content

feat(OMN-20306): developer machines get their own CI-bus login for lab work - #4430

Closed
jake-b-omni wants to merge 2 commits into
devfrom
jake/omn-20306-ci-bus-issuer
Closed

jake-b-omni wants to merge 2 commits into
devfrom
jake/omn-20306-ci-bus-issuer

Conversation

@jake-b-omni

@jake-b-omni jake-b-omni commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Why (OMN-20306)

Lab work runs on the CI bus. That covers onex lab-work run and the omni plugin's lab-run --via bus. So a developer machine needs a CI-bus login.

Today the only one is the shared ci-bus-labwork principal (OMN-20213), which is handed over by hand. That breaks onboarding's "no per-developer operator step" rule (OMN-20150 AC5).

What changed

  • A second issuer instance for lane ci-bus. Same image and code. docker/docker-compose.principal-issuer-ci-bus.yml:

    • joins omninode-ci-bus-network as an external network;
    • authenticates as the CI bus superuser (CI_BUS_KAFKA_SASL_*);
    • has its own ledger and socket volumes;
    • publishes no port.
  • deploy/lab/developer-principal-grants.ci-bus.yaml grants only what a lab-work caller needs:

    • write the unit request;
    • read the two terminals and the capacity advertisements;
    • the local.omnimarket.lab_work_client.consume.v1. group prefix;
    • cluster idempotent_write, which producers need (as OMN-20213 found).

    It grants no pool-host group, no focused-test or push-validation topics, and no CI topic.

  • The issuer accepts a cluster grant only as kafka-cluster / literal / [idempotent_write]. It reaches no topic. The dev-lane grants are unchanged.

  • developer-onboarding.yaml declares ci_bus_lane and ci_bus_issuer_url (:8444). Onboarding (omniclaude, stacked on fix(OMN-15147): float pyasn1/transformers/mcp/brace-expansion floors — clear runtime-image Trivy HIGH gate #2462) asks for this login only when the URL's /healthz answers. Declaring it before the deploy is harmless: the run says "not offered yet" and goes on.

  • Lane manifest row principal-issuer-ci-bus (optional, declared ahead of state), plus its lane-block generator entries.

  • The CI-bus isolation test treats the issuer as a network guest. A new test pins the conditions: the guest's compose must declare the bus network external and publish no port.

Operator steps (Jonah), once

  1. Write the OPERATOR-CONSENT row for per-developer CI-bus principals (Operating Rule 22).
  2. On the lab host, with the CI bus up and SASL on:
    docker compose -f docker/docker-compose.principal-issuer-ci-bus.yml --env-file <operator env file> up -d --build
    tailscale serve --bg --https=8444 "unix:$(docker volume inspect -f '{{.Mountpoint}}' omnibase-infra-principal-issuer-ci-bus_principal-issuer-socket)/issuer.sock"
    
  3. Check: curl https://<lab host tailnet name>:8444/healthz returns {"status": "ok"}.

After that, every onboarding run picks the login up with no further step.

Tests

  • New tests/scripts/test_lab_principal_issuer_ci_bus_omn20306.py: grants, refusals, rpk argv, compose wiring, facts.
  • Updated the OMN-20150 issuer tests and the CI-bus isolation test.
  • Locally: 83 passed and 9 skipped (Linux-only peer-credential tests) across the issuer, census and isolation suites. The census drift, env drift and lane-block generator gates pass.
  • tests/ci/test_canonical_clone_* fail on this Mac on plain dev too, so not this change.

🤖 Generated with Claude Code

Evidence-Ticket: OMN-20306
Evidence-Source: OCC#12172

Jake Brower and others added 2 commits October 1, 2026 08:47
…ne its own CI-bus login for lab work

Lab work runs on the CI bus, whose only lab-work login is a shared principal
handed over by hand. The same issuer, a second instance on the CI bus network,
now issues each machine its own principal with a caller-only grant set: write
the unit request, read its terminals and the capacity ads, its own client
group prefix, and cluster IdempotentWrite. The issuer accepts that one cluster
grant and nothing broader. Onboarding facts declare its URL; the script asks
only once it answers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jake-b-omni

Copy link
Copy Markdown
Contributor Author

Closing: scope change. Developers will not connect to the lab, so no CI-bus issuer is needed (OMN-20306 canceled).

@jake-b-omni jake-b-omni closed this Oct 1, 2026
@jake-b-omni
jake-b-omni deleted the jake/omn-20306-ci-bus-issuer branch October 1, 2026 14:40
jonahgabriel pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Oct 1, 2026
…12172)

* evidence(OMN-20306): author OCC companion for OmniNode-ai/omnibase_infra#4430

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 80039aac80c2f27cdb05c478a9a1f6937e7edda7.

* evidence(OMN-20306): self-bind OCC#12172 + rebind contract_sha256

---------

Co-authored-by: omnimarket-bot <bot@omninode.ai>

@github-actions github-actions 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.

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): 15
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: 15 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] docker/docker-compose.principal-issuer-ci-bus.yml (qwen3-review) — Issuer container runs as root, violating least privilege | The new docker-compose.principal-issuer-ci-bus.yml sets read_only: true but omits user: issuer, which the sibling docker-compose.principa
  • [MAJOR] scripts/lab_principal_issuer.py (qwen3-review) — Cluster grant validation accepts duplicate operations in YAML list | The validation logic in _grant() uses tuple(sorted(set(operations))) to compare against CLUSTER_OPERATIONS. This silently ded
  • [MAJOR] docker/docker-compose.principal-issuer-ci-bus.yml (qwen3-review) — Superuser credentials in environment variables are visible in /proc | The compose file passes CI_BUS_KAFKA_SASL_USERNAME and CI_BUS_KAFKA_SASL_PASSWORD into the container's environment. On Linux,
  • [MAJOR] tests/scripts/test_lab_principal_issuer_ci_bus_omn20306.py (qwen3-review) — No test that the CI bus grants file rejects a topic grant with idempotent_write | The parametrized test test_a_cluster_grant_carries_idempotent_write_and_nothing_else includes a case where a topic g
  • [MAJOR] docker/Dockerfile.principal-issuer (qwen3-review) — Two issuer instances share the same image but have divergent runtime configuration | The dev lane and CI bus issuer instances use the same Docker image (built from Dockerfile.principal-issuer) but dif
  • [MAJOR] docker/Dockerfile.principal-issuer (gpt-oss-review) — Default container command serves dev lane grants on any host | The Dockerfile for the principal issuer sets CMD to serve "--grants /app/developer-principal-grants.yaml". The CI‑bus compose overrides t
  • [MAJOR] scripts/lab_principal_issuer.py (gpt-oss-review) — Cluster ACL command omits required name argument | When granting a cluster resource, the code adds only the "--cluster" flag to the rpk command, omitting the cluster name. The rpk CLI expects a name a
  • [MINOR] docker/docker-compose.principal-issuer-ci-bus.yml (qwen3-review) — Healthcheck runs a Python subprocess every 30 seconds | The healthcheck invokes python3 scripts/lab_principal_issuer.py health --socket ... every 30 seconds. Each invocation starts a new Python inte
  • [MINOR] tests/scripts/test_lab_principal_issuer_ci_bus_omn20306.py (qwen3-review) — The _facts() parser in the test is fragile and will break on multi-line values | The _facts() helper in the test file parses the onboarding YAML by line, using a regex that matches key: value on a
  • [MINOR] tests/unit/docker/test_ci_bus_broker_isolation_omn18691.py (qwen3-review) — No test that the CI bus issuer's ledger is isolated from the dev lane's | The two issuer instances use separate named volumes (principal-issuer-ledger in the CI bus compose file vs. the dev lane's e
  • [MINOR] docker/docker-compose.principal-issuer-ci-bus.yml (qwen3-review) — The CI bus issuer's socket is published via tailscale serve with no authentication beyond the tailnet | The compose file's header comment states the socket is published on port 8444 via `tailscale ser
  • [MINOR] tests/unit/docker/test_ci_bus_broker_isolation_omn18691.py (qwen3-review) — The CI bus network guest test does not verify the guest's services have no published ports | The test test_a_ci_bus_network_guest_only_attaches_to_it asserts that no service in the guest compose fil
  • [MINOR] plan (gpt-oss-review) — Missing validation for duplicate principal_prefix across grant files | Both developer-principal-grants.yaml and developer-principal-grants.ci-bus.yaml define the same "principal_prefix: dev-". Loading
  • [MINOR] deploy/lane-census/lane-manifest.yaml (gpt-oss-review) — Optional lane declared ahead of state may cause deployment ordering issues | The lane-manifest adds the principal-issuer-ci-bus lane with "optional: true" and comments that it is "DECLARED-AHEAD-OF-ST
  • [MINOR] plan (gpt-oss-review) — No test verifies that both grant files can be loaded together without conflict | The test suite validates each grant file separately but lacks a test that loads both developer-principal-grants.yaml an

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

✅ Hostile Reviewer — REVIEWED

Critical findings: 1
Major findings: 6
Total findings: 16
Models succeeded: qwen3-review,gpt-oss-review
Models unavailable: none

Action required: findings were posted as review threads. Address or reject each one, then resolve its thread — the Hostile Review Thread Gate fails while hostile-reviewer threads are unresolved (OMN-17492).


Semantics (OMN-17492 — the model finds, thread resolution gates)

Surface Meaning Blocks merge?
Review threads Per-finding, posted by the reviewer No (informational)
Hostile Review Thread Gate Deterministic: unresolved hostile-reviewer threads exist Fails until resolved (not yet a required context)
degraded verdict Fewer than 2 models succeeded (infra) Fails this job with a named reason

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants