Repository navigation
feat(OMN-14694): broaden WS8 canary → no-io-outside-effects archetype-purity gate - #1449
Conversation
…PUTE First WS8 Class-A archetype-specific layering rule (epic OMN-2362), HOME = omnibase_core. Unlike the universal OMN-14659 lints that scan every file blindly, this COMPUTE keys off each node's declared archetype (the seam) and only flags DB-driver imports inside ORCHESTRATOR node packages. New node (mirrors OMN-14659 / #1447 exactly): - node_no_db_in_orchestrator_check_compute — def-B handle(request)->response, pure/deterministic/no-I/O. archetype_resolver.py parses each contract.yaml (node_type / descriptor.node_archetype) to find orchestrator node dirs; visitor_db_io.py AST-scans co-located .py modules for imports of sqlite3, aiosqlite, psycopg, psycopg2, asyncpg, sqlalchemy. Reuses the OMN-14656 sync file-gather EFFECT + canonical ModelValidationReport/Finding (no fork). - runtime CLI backs BOTH the pre-commit hook and the CI gate (DRY, OMN-13305): pre-commit resolves each staged file's node-package dir + sibling contract; full-tree mode delegates the walk to node_source_file_gather_effect. Enforcement, not detection (Rule #5), all in this PR: - .pre-commit-hooks.yaml remote hook (check-no-db-in-orchestrator) for peers. - .pre-commit-config.yaml self-wired hook (repo src/ is clean — the sole orchestrator, node_compliance_orchestrator, imports no DB driver). - .github/workflows/validator-no-db-in-orchestrator.yml — standalone blocking CI gate (no needs:, per OMN-14666/14668) running the unit suite + a blocking src/ self-scan; same COMPUTE node so local and CI verdicts cannot drift. RED-against-exists-but-wrong proof (test_red_* triad): the same DB-importing handler source FAILS in an ORCHESTRATOR package, PASSES in a COMPUTE package, and the clean orchestrator PASSES — proving the gate catches the real archetype-specific violation, not green-on-absence and not a blind scan. Ratchet hygiene (side fixes, no gate loosened): - Converted the 5 WS8-family handlers (OMN-14656/14659) + this one to model_dump(mode="json") — behaviour-identical (all finding fields are JSON-safe; severity is Literal[str], not an enum) — removing 5 pre-existing bare-model_dump violations (314->309) and lowering the ratchet ceiling to 309. - Allowlisted archetype_resolver.py in .yaml-validation-allowlist.yaml (structural read of heterogeneous contract.yaml; same pattern as operation_match_requires_operation.py). Closes OMN-14694
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 19 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (21)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…ype-purity gate Reframe per OMN-14662 (operator decision 2026-07-16, "architectural purity always"): the DB-only ORCHESTRATOR seed becomes the single archetype-purity invariant `no-io-outside-effects` (validator_id `arch-no-io-outside-effects`). EFFECT is the only I/O-permitted archetype; every .py module co-located with a non-EFFECT contract (COMPUTE / REDUCER / ORCHESTRATOR) must be pure. Rename + broaden (same COMPUTE, same def-B handle(request)->ModelValidationReport, same paired EFFECT file-gather, canonical ModelValidationReport/Finding — no fork): - node_no_db_in_orchestrator_check_compute -> node_no_io_outside_effects_check_compute - archetype_resolver: contract_declares_orchestrator -> resolve_archetype() -> EnumNodeArchetype | None; seam generalized _orchestrator_dirs -> _non_effect_dirs (fail-closed: only a positively-declared EFFECT contract is exempt). - visitor_db_io (DB imports only) -> visitor_io (IoSurfaceVisitor), FULL forbidden surface set: database (sqlite3/aiosqlite/psycopg/psycopg2/asyncpg/sqlalchemy), network/HTTP (httpx/requests/aiohttp/urllib3/socket/urllib.request), subprocess, git (git/pygit2 import OR subprocess argv[0]==git, ALL verbs), Linear (SDK import OR linear.app URL literal), filesystem WRITES (open write-mode, os/shutil mutators, pathlib.Path write methods), direct event-bus instantiation (KafkaProducer/AIOKafka*/ confluent_kafka.*/*EventBus), direct infra-adapter instantiation (*Adapter). `# db-io-ok` -> `# io-ok:` suppression. RED-against-exists-but-wrong per surface: the SAME I/O source is FLAGGED in a non-EFFECT package and PASSES verbatim inside an EFFECT package (archetype discriminator), plus clean non-EFFECT PASS. Reads, str.replace, urllib.parse are correctly not flagged (false-positive traps closed). 138 unit tests pass. Enforcement (rule #5): pre-commit hook check-no-io-outside-effects + standalone blocking CI gate validator-no-io-outside-effects.yml (unit suite + green full-tree src/ self-scan; same COMPUTE node so local and CI cannot drift). Blast-radius measured before landing: broadened self-scan on omnibase_core/src is clean (0 hits). Closes OMN-14694
… docstring (AI-slop md_separator strict gate)
* evidence(OMN-14694): author OCC companion for OmniNode-ai/omnibase_core#1449 OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 5b0c4e337a466608ab6365ba88cfb520ad7cd54d. * evidence(OMN-14694): self-bind OCC#4285 + rebind contract_sha256 * evidence(OMN-14694): repair core 1449 OCC companion * evidence(OMN-14694): add deploy scope for core 1449 --------- Co-authored-by: codex-gpt-5 <codex@omninode.ai>
Ticket
Closes OMN-14694 (WS8 canary — no-db-in-orchestrator ValidatorNode COMPUTE), first Class-A rule under parent OMN-14662, epic OMN-2362 (Generic Validator Node Architecture). Operator resolved WS8 HOME = omnibase_core.
What
The first WS8 archetype-specific layering rule converted to a canonical
ValidatorNodeCOMPUTE. Unlike the universal 4 rules shipped in OMN-14659 / #1447 (which AST-scan every file blindly), this rule keys off each node's declared archetype and only flags DB-driver imports inside ORCHESTRATOR node packages.Mirrors the OMN-14659 / #1447 shape exactly, reusing the OMN-14656 / #1446 sync file-gather EFFECT + canonical
ModelValidationReport/ModelValidationFinding(no forked models):node_no_db_in_orchestrator_check_compute— def-Bhandle(request) -> response, pure / deterministic / no I/O, no event-envelope import.archetype_resolver.pyparses eachcontract.yamlto find orchestrator node directories.visitor_db_io.pyAST-scans the co-located.pymodules for imports ofsqlite3,aiosqlite,psycopg,psycopg2,asyncpg,sqlalchemy.runtime_no_db_in_orchestrator_check.pyCLI backs both the pre-commit hook and the CI gate (DRY, OMN-13305). The filesystem walk is delegated to the paired EFFECT (node_source_file_gather_effect); the COMPUTE stays pure over in-memory strings.The seam (field it keys on)
Top-level
node_typeanddescriptor.node_archetypein each node'scontract.yaml. A node directory is an ORCHESTRATOR package when either equalsorchestrator(sourced fromEnumNodeArchetype.ORCHESTRATOR, so a vocabulary rename breaks loudly). Only.pyfiles whose parent directory equals such a contract's directory are DB-scanned — the archetype fact, not a blind every-file scan, decides scope.Enforcement, not detection (Rule #5) — all in this PR
.pre-commit-hooks.yaml→check-no-db-in-orchestrator(for consuming repos)..pre-commit-config.yaml(reposrc/is clean — the sole orchestrator,node_compliance_orchestrator, imports no DB driver; verified full-tree scan = PASS)..github/workflows/validator-no-db-in-orchestrator.yml— standalone, noneeds:(per the OMN-14666/14668 skip-then-vacuous-green lesson), runs the unit suite + a blockingsrc/self-scan. Same COMPUTE node backs hook + gate, so local and CI verdicts cannot drift. Suggested required-status context:No DB In Orchestrator Validator / validate.RED-against-exists-but-wrong proof
tests/unit/nodes/node_no_db_in_orchestrator_check_compute/test_node_no_db_in_orchestrator_check_compute.py— the load-bearingtest_red_*triad drives the same DB-importing handler source through three placements and asserts the gate discriminates on archetype, not on the mere presence of DB code:test_red_orchestrator_handler_with_db_io_fails— orchestrator contract + a handler that doesimport sqlite3; sqlite3.connect(...)→ FAIL, one finding athandler.py:1, message namessqlite3and "DB access in ORCHESTRATOR node". (exists-but-wrong is caught, not silently green.)test_red_compute_handler_with_db_io_passes— the identical DB-importing handler in a COMPUTE package → PASS. Proves the FAIL above is real archetype-keying, not an artefact of the DB source existing.test_red_clean_orchestrator_passes— orchestrator + clean handler → PASS (not a blanket "orchestrator == fail").Plus: both-seam-field coverage, every forbidden module (incl. dotted
sqlalchemy.orm/psycopg.rows),# db-io-oksuppression, relative-import non-trip, dir-scoping (DB import in a sibling non-orchestrator package passes), and ERROR findings for unparseable contract YAML / handlerSyntaxError. 34 node tests + 131 across the whole WS8 family all pass.dod_evidence
uv run pytest tests/unit/nodes/node_no_db_in_orchestrator_check_compute/ -q→ 34 passed; whole WS8 family → 131 passed.uv run mypyon the WS8 node handlers → Success, no issues (25 files).ruff format+ruff check→ clean.python -m ...runtime_no_db_in_orchestrator_check --root src→ exit 0, "OK: No database I/O found in ORCHESTRATOR node packages".pre-commiton all changed files → green (committed with no--no-verify).Ratchet hygiene (side fixes, no gate loosened)
model_dump(mode="json")— behaviour-identical (allModelValidationFindingfields are JSON-safe;severityisLiteral[str], not an enum) — removing 5 pre-existing bare-model_dump()violations that feat(OMN-14659): WS8 fan-out — 4 canonical arch-* ValidatorNode COMPUTE nodes #1447 left above the ceiling (314 → 309) and lowering--max-violations310 → 309.archetype_resolver.pyin.yaml-validation-allowlist.yaml(structural read of heterogeneouscontract.yaml; same pattern asoperation_match_requires_operation.py/node_compliance_scan_compute);test_yaml_allowlist.py→ 10 passed.Not in this PR
Evidence-Ticket: OMN-14694
Evidence-Source: OCC#4285