Skip to content

feat(OMN-10407): durable-evidence gate before Linear Done transition - #467

Merged
jonahgabriel merged 2 commits into
mainfrom
jonah/omn-10407-durable-evidence-gate
Apr 30, 2026
Merged

jonahgabriel merged 2 commits into
mainfrom
jonah/omn-10407-durable-evidence-gate

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Apr 30, 2026 •

Copy link
Copy Markdown
Contributor

Context

Cites OMN-10407.

OMN-9855 incident (2026-04-30): a worker transitioned the Linear ticket to Done after:

  1. Probing that the implementation was already on omnibase_core/main (PR feat(OMN-12323): implement ticketing runtime handlers #949 merged 2026-04-27).
  2. Generating a DoD receipt at onex_change_control/evidence/OMN-9855/dod_report.json LOCALLY, never committing it.
  3. Updating the Linear dod_evidence description to point at PR feat(OMN-12323): implement ticketing runtime handlers #949.

Result: Linear was green but onex_change_control/main still had the OLD contract citing superseded PR #926. The durable evidence trail was broken — Linear-Done state was performative and unverifiable from origin alone.

What this PR does

Adds a pure-logic DurableEvidenceGate service in node_dod_verify that refuses Linear Done when any of three checks fails:

  1. RECEIPT_TRACKED — evidence/<TICKET>/dod_report.json must be tracked on onex_change_control/main (not just present on disk).
  2. CONTRACT_CITES_MERGE_COMMIT — every cited pr_url has gh-state MERGED and mergeCommit.oid matches the cited commit_sha. Closed/superseded PRs HARD FAIL.
  3. CONTRACT_ON_OCC_MAIN — the contract version on OCC main contains the real merge-commit citation. Stale main HARD FAIL with explicit "open an OCC PR first" remediation hint.

Failure raises DurableEvidenceGateError carrying the structured ModelDurableEvidenceGateResult; the first failed check supplies the remediation hint.

Architecture

  • Pure gate + Protocol-typed probes (GitTrackedProbe, GhPrViewProbe, ContractOnRefLoader). Tests inject deterministic stubs.
  • New schema module model_durable_evidence_gate.py is pure (no I/O, env, time) per OCC D-008 schema-purity rules.
  • Production probe wiring (subprocess-backed git ls-tree, gh pr view --json mergeCommit, yaml-load-on-git-ref) is intentionally out of scope for this slice. A follow-up ticket will wire concrete probes and integrate the gate into the ticket-pipeline FSM phase ordering immediately before any Linear Done transition.

DoD evidence

  • dod-001 — uv run pytest tests/unit/nodes/node_dod_verify/test_durable_evidence_gate.py -v (16 tests pass).
  • dod-002 — test_untracked_receipt_hard_fails (covers OMN-9855 incident shape).
  • dod-003 — test_contract_cites_superseded_pr_hard_fails (closed PR cited).
  • dod-004 — test_stale_occ_main_hard_fails (main has older contract version).

Receipt-Gate citation: OMN-10407 (this ticket); evidence captured in contracts/OMN-10407.yaml.

Verification

  • 16 new unit tests pass; full tests/unit/nodes/node_dod_verify/ suite is 67/67 green.
  • Full uv run pytest tests/ -m "not kafka and not integration" is 2783 passed / 0 failed.
  • uv run mypy src/omnimarket/nodes/node_dod_verify/ --strict clean.
  • uv run ruff check and uv run ruff format --check clean.
  • pre-commit run --all-files green (with OMNIBASE_INFRA_PATH set per cross-repo lint).

Test plan

  • Untracked receipt → HARD FAIL with remediation hint
  • Cited PR is CLOSED/superseded → HARD FAIL
  • Cited PR is MERGED but mergeCommit.oid mismatches → HARD FAIL
  • Stale OCC main (still cites old PR) → HARD FAIL
  • Contract missing on OCC main → HARD FAIL
  • All checks green → PASS
  • enforce() raises DurableEvidenceGateError carrying structured result
  • Citation extraction handles top-level, nested-in-checks, dedup, malformed
  • PR URL parser rejects non-pull URLs and empty input

Summary by CodeRabbit

  • New Features

    • Added durable-evidence gate validation that prevents ticket completion without verifying receipt tracking, confirming cited pull requests are merged with correct commits, and validating contract integrity on the main branch.
  • Tests

    • Added comprehensive test suite for durable-evidence gate validation across multiple failure scenarios and successful completion paths.

Adds a pure-logic DurableEvidenceGate service in node_dod_verify that
refuses Linear Done when the durable evidence trail is local-only.

OMN-9855 incident shape (2026-04-30):
- Worker probed implementation already on omnibase_core/main (PR #949)
- Generated DoD receipt LOCALLY at evidence/OMN-9855/dod_report.json,
  never committed
- Updated Linear dod_evidence text to point at PR #949
- onex_change_control/main still had stale contract citing superseded #926
- Linear flipped Done; durable trail unverifiable from origin alone

The gate enforces three checks before any Linear Done transition:

1. RECEIPT_TRACKED — evidence/<TICKET>/dod_report.json must be tracked
   on onex_change_control/main (not just present on disk).
2. CONTRACT_CITES_MERGE_COMMIT — every cited pr_url has gh-state MERGED
   and mergeCommit.oid matches the cited commit_sha. Closed/superseded
   PRs HARD FAIL.
3. CONTRACT_ON_OCC_MAIN — the contract version on OCC main contains the
   real merge-commit citation. Stale main HARD FAIL with explicit "open
   an OCC PR first" remediation hint.

Failure raises DurableEvidenceGateError carrying the structured
ModelDurableEvidenceGateResult; the first failed check supplies the
remediation hint.

Architecture:
- Pure-logic gate + Protocol-typed probes (GitTrackedProbe,
  GhPrViewProbe, ContractOnRefLoader). Tests inject deterministic stubs.
- New schema module model_durable_evidence_gate.py is pure (no I/O,
  no env, no time) per onex_change_control D-008 schema purity rules.
- Production probe wiring (subprocess-backed git ls-tree / gh pr view /
  yaml load on git ref) is intentionally out of scope for this slice;
  follow-up ticket will wire the gate into the FSM phase ordering.

DoD evidence:
- 16 unit tests cover untracked receipt, superseded PR, wrong SHA,
  stale main, missing-on-main, structured error raise, citation
  extraction (top-level + nested + dedup + malformed), URL parser.
- All 2783 non-kafka non-integration omnimarket tests pass.
- mypy --strict clean on src/omnimarket/nodes/node_dod_verify/.
- ruff format + check clean; pre-commit hooks all green.
@coderabbitai

coderabbitai Bot commented Apr 30, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@jonahgabriel has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 5 minutes and 28 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 62728e59-fad5-49db-ba48-238aa0422ec8

📥 Commits

Reviewing files that changed from the base of the PR and between bbd5e04 and 3ac1b91.

📒 Files selected for processing (3)
  • contracts/OMN-10407.yaml
  • src/omnimarket/nodes/node_dod_verify/services/durable_evidence_gate.py
  • tests/unit/nodes/node_dod_verify/test_durable_evidence_gate.py
📝 Walkthrough

Walkthrough

This pull request introduces a new "durable evidence gate" feature that validates whether a Linear ticket can transition to Done status. The implementation includes a contract specification, Pydantic models for structured results, a service that orchestrates three verification checks (receipt tracking, GitHub PR merge status, contract integrity), and comprehensive test coverage.

Changes

Cohort / File(s) Summary
Contract Configuration
contracts/OMN-10407.yaml
New contract specification enforcing durable-evidence gate before Linear Done transition, with CI evidence requirements, emergency bypass settings, and four manual DoD evidence items including hard-fail surfaces for receipt tracking, PR merge state, contract citations, and OCC main staleness.
Models
src/omnimarket/nodes/node_dod_verify/models/model_durable_evidence_gate.py
New Pydantic module defining enums for check types and status (pass/fail), plus frozen BaseModel schemas for individual check results, aggregate gate results with ticket ID and check list, and cited merge-commit records with validated PR URLs, repo derivation, and commit SHA.
Service Implementation
src/omnimarket/nodes/node_dod_verify/services/durable_evidence_gate.py
New service implementing the core gate logic with evaluate() and enforce() methods that perform three checks: receipt JSON path tracking on OCC main, GitHub PR merge state and commit SHA validation via configurable probes, and contract version consistency on OCC main. Includes helper functions for PR URL parsing and citation extraction from contract structures, plus Protocol types for dependency injection.
Tests
tests/unit/nodes/node_dod_verify/test_durable_evidence_gate.py
Comprehensive test suite covering failure modes (untracked receipt, non-merged PR citations, wrong merge SHA, stale contracts), pass path validation, citation parsing with deduplication and malformed entry skipping, PR URL canonicalization, and exception handling in enforce().

Sequence Diagram

sequenceDiagram
    participant Client as Caller
    participant Gate as DurableEvidenceGate
    participant Tracker as GitTrackedProbe
    participant GH as GhPrViewProbe
    participant OCC as ContractOnRefLoader
    
    Client->>Gate: evaluate(ticket_id, contract, receipt_path, contract_path)
    
    activate Gate
    
    Note over Gate: Check 1: Receipt Tracking
    Gate->>Tracker: is_tracked(receipt_path, "main")
    Tracker-->>Gate: tracked: bool
    
    Note over Gate: Check 2: PR Merge Status & SHA
    Gate->>Gate: extract_cited_merge_commits(contract)
    Gate->>GH: gh_pr_view(repo, pr_number)
    GH-->>Gate: {state, merge_commit_oid}
    Gate->>Gate: validate merge_commit_oid == cited_sha
    
    Note over Gate: Check 3: Contract on OCC Main
    Gate->>OCC: load_contract_on_ref(contract_path, "main")
    OCC-->>Gate: occ_contract
    Gate->>Gate: extract_cited_merge_commits(occ_contract)
    Gate->>Gate: verify local citations ⊆ occ citations
    
    Gate->>Gate: aggregate results → ModelDurableEvidenceGateResult
    Gate-->>Client: result (PASS or FAIL with check messages)
    
    deactivate Gate
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A gate so durable, crafted with care,
Checks receipt paths and merge commits fair,
No ticket skips without proof in hand—
Three stellar checks make the Done so grand!
GitHub and OCC in harmony dance,
Evidence sealed with a rabbit's romance. 🎯

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: implementing a durable-evidence gate feature for OMN-10407 that prevents Linear Done transitions. It matches the core functionality introduced across the contract specification, models, service, and tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonah/omn-10407-durable-evidence-gate

Review rate limit: 0/5 reviews remaining, refill in 5 minutes and 28 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Apr 30, 2026 •

Copy link
Copy Markdown

⚠️ Hostile Reviewer — DEGRADED (informational)

Blocking findings (critical/error): 0
Total findings: 0
Models succeeded: none

Note: All reviewer models failed or were unavailable. Degraded results are informational during the pilot phase (OMN-8524) and do not block merge. Error: cli_review exited non-zero (all models failed or binary error)


Gate semantics (pilot phase)

Verdict Meaning Blocks merge?
passed No critical/error findings No
blocked CRITICAL or ERROR findings found Yes
degraded All models unavailable (infra) No (pilot)

Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/omnimarket/nodes/node_dod_verify/services/durable_evidence_gate.py`:
- Around line 148-151: The deduplication currently keys on raw pr_url so
semantically-equivalent citations like "/pull/123" and "/pull/123/files" are
treated as different; update the logic that builds the dedupe key (the code that
creates key = (pr_url, sha) and uses seen.add key) to first normalize the PR
identity by calling parse_pr_url(pr_url) (or the existing normalizing helper)
and use the normalized PR URL/ID together with sha when constructing key; apply
the same change to the second occurrence around the block that references
gh_pr_view() and CONTRACT_ON_OCC_MAIN so both dedupe sites compare normalized
citations.
- Around line 141-159: The loop currently accepts any string `sha` and passes it
to ModelCitedMergeCommit which raises on malformed short SHAs; before creating
ModelCitedMergeCommit (after parse_pr_url(...) and before using `key = (pr_url,
sha)` or appending), validate `sha` (e.g. ensure it matches a hex SHA pattern
like 7–40 hex chars) and if it doesn't match, continue/skip that candidate so
malformed short SHAs are ignored rather than causing a ValidationError;
alternatively wrap ModelCitedMergeCommit construction in a try/except for the
validation error and continue on exception to achieve the same behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f868430c-5850-436a-a52e-b9001a4d23c5

📥 Commits

Reviewing files that changed from the base of the PR and between 6bedf70 and bbd5e04.

📒 Files selected for processing (4)
  • contracts/OMN-10407.yaml
  • src/omnimarket/nodes/node_dod_verify/models/model_durable_evidence_gate.py
  • src/omnimarket/nodes/node_dod_verify/services/durable_evidence_gate.py
  • tests/unit/nodes/node_dod_verify/test_durable_evidence_gate.py

Comment thread src/omnimarket/nodes/node_dod_verify/services/durable_evidence_gate.py Outdated
@github-actions
github-actions Bot enabled auto-merge April 30, 2026 18:47
CR Major #1 (durable_evidence_gate.py:~141-159):
extract_cited_merge_commits accepted any string sha and let
ModelCitedMergeCommit (min_length=7) raise ValidationError on
malformed short SHAs — contract violation vs the docstring's
"malformed citations are skipped" promise. Added _SHA_RE guard
([0-9a-fA-F]{7,40}) before parse_pr_url; malformed SHAs are now
silently skipped. Regression test:
test_extract_skips_malformed_short_sha.

CR Major #2 (same file, dedupe + cross-set comparison):
Citation dedupe and CONTRACT_ON_OCC_MAIN comparison were keyed on
raw pr_url, so /pull/123 and /pull/123/files for the same PR were
treated as distinct citations — caused double gh_pr_view() calls
AND false CONTRACT_ON_OCC_MAIN hard-fails when local and OCC main
spelled the same PR differently. Switched both keys to the
normalized identity (repo, pr_number, sha). Regression tests:
test_url_variants_dedupe_to_same_citation and
test_url_variants_across_local_and_main_do_not_hard_fail.

deploy-gate root cause:
Action matcher src/*/nodes/**/*.py flagged the pure-logic gate
service as a runtime path. Added dod-005 to contracts/OMN-10407.yaml
documenting the deploy posture honestly: this slice is pure logic
+ Protocol probes, no container/topic touched, and concrete probe
wiring + FSM integration ship in a follow-up ticket carrying its
own deploy evidence. check_value contains "deploy" so the gate
recognizes intent. NO skip token used.

Verification:
- 70/70 node_dod_verify unit tests green (was 67, +3 new).
- Full uv run pytest tests/ -m "not kafka and not integration":
  2786 passed / 0 failed (was 2783).
- uv run ruff format/check, uv run mypy --strict on
  node_dod_verify/, all clean.
- OMNIBASE_INFRA_PATH=... pre-commit run --all-files: all hooks
  pass.
- Local replay of validate_pr_deploy_required.py against the
  three changed files now returns DEPLOY GATE PASSED.

CR fingerprints (CodeRabbit auto-resolves on resolution):
phantom:medusa:ocelot:97a9ca79-253e-49f4-bb67-27581b204d27
4e71b3a2
@jonahgabriel
jonahgabriel added this pull request to the merge queue Apr 30, 2026
Merged via the queue into main with commit 7647d8e Apr 30, 2026
27 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-10407-durable-evidence-gate branch April 30, 2026 20:47
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.

1 participant