Skip to content

feat(reputation): add versioned outbound reputation contracts - #175

Draft
seonghobae wants to merge 85 commits into
mainfrom
feat/site-reputation-contract-v1
Draft

feat(reputation): add versioned outbound reputation contracts#175
seonghobae wants to merge 85 commits into
mainfrom
feat/site-reputation-contract-v1

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Purpose and bounded context

Introduce the first versioned, transport-neutral Rust contract core for Wardnet outbound destination reputation. Wardnet owns destination maliciousness, evidence lifecycle, security policy and SOC explanation. This crate deliberately does not parse or authorize URLs, resolve DNS, validate peers, follow redirects, choose proxies, establish TLS, perform HTTP I/O, persist state, or claim that a policy decision blocked traffic. Those executable transport authorities remain EgressWeave-owned.

This PR stays Draft until one cleanup head has complete exact-current evidence and normally satisfiable governance. It is not a runtime interceptor and does not consume a mutable EgressWeave dependency.

Implemented contract slice

crates/wardnet-reputation-core provides wardnet.reputation.v1 contracts for authenticated outbound context, canonical destination subjects, versioned source evidence, reviewed source policy, immutable policy snapshots, independent assessment/evidence-health/action/reason dimensions, and explainable decision envelopes. Validation is bounded and fail closed across schema identity, text/list limits, subject scope, time ordering, confidence, enforcement provenance, source tenant eligibility, decision evidence, assessment/reason/action coherence and unsafe allow states.

All v1 wire structs reject unknown fields. Reviewed source eligibility is explicit across tenants as well as purposes/subject kinds. The core preserves KnownMalicious, Suspicious, and Unknown rather than manufacturing benign probability or transport authorization. Required evidence Expired/Unavailable takes reason precedence as RequiredAuthorityUnavailable; adverse assessments and unhealthy required evidence cannot serialize as Allow; business authorization is the only coherent reputation-only allow reason in this slice.

The v1 contract enforces Proposed #173's initial size boundaries without widening unrelated lists: ObservableUrl permits 8 KiB while ordinary bounded text remains 1 KiB, generic bounded lists remain 64 items, and DecisionEnvelopeV1.evidence_refs is capped at 32.

TDD and review lineage

Retained causal repairs include:

  • adverse/unhealthy allow attempts return the specific fail-closed errors before generic action/reason inconsistency;
  • every v1 wire struct rejects unknown fields;
  • source tenant eligibility is explicit through tenant_scope plus bounded allowed_tenant_ids;
  • Proposed docs(egress): plan Wardnet outbound site reputation engine #173's 8 KiB observable-URL boundary was proven by executed RED dd5a82df0d5588b7f35003fb7447902c10641719 / CI 34060554728 and repaired narrowly in 2f7d504165d82f85d52a8cdaebe53662b4623826;
  • the 32/33 evidence_refs regression was added before the decision-specific production cap. Causal source fix 2b9e9265fa948c65adfe5156ff4838371d79baf9 introduces MAX_DECISION_EVIDENCE_REFS_V1 = 32 and leaves the generic 64-item list limit unchanged.

A temporary write-capable PR-head repair workflow was rejected after CodeQL identified unsafe PR-head checkout. It was removed at 53caa4262ba51f066d932f8ec8c25ef79ff9ed62; both CodeQL threads are resolved/outdated and no privileged self-repair workflow remains. Fresh review-thread inventory on current head has zero unresolved findings. CodeRabbit/Devin/model evidence remains advisory and is not treated as human approval.

Focused verifier RCA and cleanup

Issue #177 exposed that temporary focused verifier jobs accumulated without acquiring a runner because they selected unsupported macos-15-arm64. The selector was corrected to supported macos-15, with PR-scoped workflow concurrency. On exact predecessor 1a8684305e8675b967719b2de3c384b4c03b0b9a, precedence verifier 34071919210 / job 101590722347 and evidence-cap verifier 34071919222 / job 101590722100 acquired hosted runners, asserted exact source, passed formatting and their focused tests, and terminated success. Those purpose-complete workflows are absent from the cleanup head; their historical results prove only the causal tests and are not merge-gate substitutes.

Research and standards traceability

crates/wardnet-reputation-core/TRACEABILITY.md links the contract to NIST CSF 2.0, NIST SP 800-218 SSDF 1.1, MITRE CWE-20 and Chandola et al. (2009). It records why anomaly/evidence uncertainty is preserved and why unrelated load-balancing literature is not causal authority for this transport-neutral contract core. src/lib.rs and src/model.rs link the traceability boundary. Redistributable rights are not assumed for third-party PDFs; durable bibliographic/DOI references are retained instead.

Foreign-owner boundaries

PR #173 remains the Proposed architecture/design lane. #175 implements only the pure Wardnet-owned contract core and does not mark #173 Accepted.

EgressWeave remains the reusable transport-authorization owner. Production integration requires an immutable compatible EgressWeave release/ACL; no mutable sibling source/PR head, source copy, DNS/address/redirect/proxy/TLS duplicate, or cross-service SQL is accepted. Current EgressWeave release inventory is empty, so this PR does not claim released transport integration.

context-graph-contracts and enterprise-architecture-core remain read-only foreign-owner dependencies from this writer. No mutable Context Fabric head is Wardnet production authority, and Wardnet maliciousness/risk verdicts are not promoted into authoritative EA truth.

Current exact state — 2026-09-07 KST

Protected/default base remains exact main@a52ccd0a24a727d9349bb32def7713882d8cad1e. Current cleanup head remains exact 9de0ea568096a18b5c1fc9bc9fce097e08584d44, open/Draft/mergeable. Purpose-complete focused workflows remain removed and the product/test/docs delta is unchanged.

Fresh exact-head repository evidence is now:

  • CI 34071995169SUCCESS;
  • Fuzz 34071995140SUCCESS;
  • Security Scan 34071995181SUCCESS;
  • SAST Semgrep 34071995128SUCCESS;
  • CodeQL PR 34071995171FAILURE.

CodeQL's Detect CodeQL languages job 101590923807 acquired hosted runner 1001730119, checked out the exact head and completed success. Compatibility job 101597707181 acquired hosted runner 1001731487; Request current-head CodeQL scan dispatch completed success, while Release runner or enforce current-head CodeQL verdict failed. This isolates the current first failing boundary to delegated/current-head CodeQL verdict publication after successful leaf dispatch, not repository checkout, runner acquisition, changed-path detection or Wardnet source execution. The canonical owner specimen remains ContextualWisdomLab/.github#1929; this failure is non-passing and is not converted into a bypass or predecessor verdict.

Child #176 has now been non-force reconstructed onto this exact parent while remaining Draft. Its 32-reference inherited regression was proven RED and minimally repaired GREEN, the parent's 8 KiB observable-URL invariant/test was retained, and its temporary focused verifier was removed after exact success. It must still wait for #175 protected integration and reacquire its own full current-head gates before promotion.

Live organization governance remains owner-plane work under .github#772: self/model approval, routine administrator bypass, force push/destructive rebase, gate weakening and predecessor-evidence transfer remain forbidden.

Completion boundary

Keep Draft until the unchanged cleanup head has terminal success for every then-live repository/security/central gate, zero valid unresolved review findings, fresh candidate-base compatibility, and governance that permits the ordinary protected merge path. Do not claim runtime enforcement, immutable release readiness, or protected integration before those conditions are true.

@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

워크스페이스에 wardnet-reputation-core 크레이트를 추가했습니다. 이 크레이트는 목적지, 증거, 정책, 결정 봉투의 버전 계약과 검증 로직을 제공합니다. 통합 테스트와 JSON 픽스처도 추가했습니다.

Changes

사이트 평판 계약

Layer / File(s) Summary
크레이트 등록과 공개 표면
Cargo.toml, crates/wardnet-reputation-core/Cargo.toml, crates/wardnet-reputation-core/src/lib.rs
워크스페이스에 새 크레이트를 등록했습니다. serdeserde_json 의존성을 선언했습니다. model 모듈을 공개하고 내용을 재내보냅니다.
목적지·증거·정책 계약
crates/wardnet-reputation-core/src/model.rs
아웃바운드 목적지, 증거 레코드, 소스 정책, 정책 스냅샷과 각 검증 규칙을 추가했습니다. 스키마, 텍스트 길이, 목록 크기, 시간 순서, 신뢰도, 출처 조건을 검증합니다.
결정 계약과 정합성 검증
crates/wardnet-reputation-core/src/model.rs
평판 평가, 증거 상태, 조치, 사유, 결정 봉투를 추가했습니다. 평가·사유·조치 조합, 증거 참조, 증거 상태, 만료 시각을 검증합니다.
계약 검증과 픽스처 테스트
crates/wardnet-reputation-core/tests/contract.rs, crates/wardnet-reputation-core/tests/decision_binding.rs, tests/fixtures/reputation/v1/exact_host_roundtrip.json
잘못된 방향과 스키마, 빈 필드, 모호한 범위, 잘못된 시간과 신뢰도, 출처 누락을 검증합니다. 결정 봉투의 허용·거부 조합과 JSON 왕복 안정성을 확인합니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Merge Risk: 🔵 Low · up to f89c2

Runtime contract behavior is not currently blocked, but the research documentation and provenance regression assertion should receive bounded follow-up.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 69.23% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 39 functions across 4 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 버전이 지정된 아웃바운드 평판 계약을 추가하는 PR의 주요 변경 사항을 정확하고 간결하게 설명합니다.
Full details: Docstring Coverage

Explanation

Docstring coverage is 69.23% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 39 functions across 4 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/site-reputation-contract-v1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor Author

Exact-state override — 2026-09-07 KST

The test-only source head dd5a82df0d5588b7f35003fb7447902c10641719 has now produced the required hosted RED. CI 34060554728, job 101560199069, acquired ubuntu-24.04, passed formatting and executed cargo test --locked --workspace; the sole failure in the reputation contract suite was enforces_declared_observable_url_v1_limit, where an exactly 8 KiB ObservableUrl was rejected as BoundExceeded("subject.value"). The other 13 reputation-contract tests passed, so this is the declared subject-bound drift rather than a runner/setup failure.

Current branch head is 0282c9d57058783b79cc9ba832ef319cbde7774e, which adds a temporary bounded repair workflow only. Run 34061489186 is queued before job steps. The workflow does not execute repository tests/code under contents: write: it verifies the source event/RED ancestry, applies exact-anchor text transformations that add only the 8 KiB ObservableUrl limit while preserving the generic 1 KiB text limit for host/address/identity fields, validates the two-path diff, verifies the remote head is unchanged, removes itself, and normal fast-forward pushes the repair. No force update or global bound widening is authorized. After that head materializes, reacquire exact-current CI/security/fuzz/review evidence; predecessor results do not transfer.

@seonghobae seonghobae added enhancement New feature or request priority: medium Normal-priority or P2 work status: draft type: feature New or expanded product capability labels Sep 6, 2026 — with ChatGPT Codex Connector
Comment thread .github/workflows/reputation-evidence-ref-limit-repair.yml Fixed
Comment thread .github/workflows/reputation-evidence-ref-limit-repair.yml Fixed

Copy link
Copy Markdown
Contributor Author

Fresh contract/code review found a bounded v1 drift against parent design #173: the Proposed design fixes the initial decision envelope at 32 returned evidence references, while current DecisionEnvelopeV1::validate() routes evidence_refs through the generic 64-item list bound.

TDD lineage is now explicit on this branch. Test-only 01270cfe68e24ccb39d912b6aae6777450d877bf adds decision_evidence_ref_limit.rs: 32 refs must validate and 33 must fail with BoundExceeded("evidence_refs"). 47f3683784d4abe4e516e70859a6aaa838982597 adds a read-only exact-source focused verifier; current a480d94e0e12349cf815f74a5cb2982c0e67af8b adds a bounded repair workflow whose first job must prove that specific hostile test RED before its write job may add a decision-only 32-ref limit and remove the repair workflow. The generic 64-item policy/provenance/source-list bound is intentionally not narrowed.

All new hosted lanes are currently materialized but queued; no executed RED or GREEN is claimed yet. The branch remains Draft. The repair job additionally refuses to push if the live PR head changed, and uses a normal non-force push only after the exact-source RED succeeds.

Copy link
Copy Markdown
Contributor Author

Causal source repair is now on exact head 2b9e9265fa948c65adfe5156ff4838371d79baf9: DecisionEnvelopeV1 has a decision-specific 32-reference bound before the existing generic text-list validation; the 64-item bound remains unchanged for source-policy/provenance lists. The hostile 32/33 regression remains permanent.

A temporary self-repair workflow briefly introduced at a480d94e... was rejected by fresh CodeQL review because its write-capable job checked out PR-head code. I removed that workflow entirely at App-authored 53caa4262ba51f066d932f8ec8c25ef79ff9ed62 and resolved both now-outdated review threads only after verifying the file deletion. No privileged PR-head repair workflow remains in the tree.

Current exact-head CI/Security/SAST/CodeQL/Fuzz plus the two read-only focused verifiers are materialized but queued/pending; no exact-head GREEN is claimed. Keep Draft.

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

Labels

enhancement New feature or request priority: medium Normal-priority or P2 work status: draft type: feature New or expanded product capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants