Skip to content

feat: bind approved destinations to TCP peers - #5

Merged
seonghobae merged 40 commits into
mainfrom
feat/direct-socket-binding
Aug 6, 2026
Merged

feat: bind approved destinations to TCP peers#5
seonghobae merged 40 commits into
mainfrom
feat/direct-socket-binding

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Buyer-visible problem

A resolver policy can approve and pin one or more addresses, but that decision alone does not prove that the operating system connected to the approved IP and port. A later adapter could resolve again, inherit proxy settings, substitute another address, attach unapproved IPv6 interface metadata, or expose a stream before checking its remote peer.

Delivered vertical slice

Reusable direct-only Rust network kernel

  • Added the independently reusable originweave-network crate.
  • Accepts only one explicit canonical SocketAddr already authorized by a ResolutionSnapshot.
  • Rejects port zero, zero or excessive timeouts, attempt counts outside 1..=4, unapproved addresses, IPv4-mapped IPv6 forms that differ from the canonical approved address, and nonzero IPv6 flow or scope metadata that the destination snapshot did not authorize.
  • Uses a non-cloneable ConnectionPlan consumed by one bounded connection sequence.
  • Calls TcpStream::connect_timeout with the exact approved address and never accepts a hostname or reads ambient proxy variables.
  • Verifies TcpStream::peer_addr before exposing the stream and requires exact IP-and-port equality.
  • Emits credential-free origin, requested-peer, observed-peer, destination-class, successful-attempt, and timeout evidence.
  • Preserves destination-policy and operating-system failures through standard Display, std::error::Error, and source() chains.

Realistic and deterministic verification

  • Real loopback TcpListener/TcpStream integration proof.
  • Closed-port connection-refusal and exact attempt-bound test.
  • Deterministic timeout, retry-then-success, peer-inspection failure, and peer-mismatch tests.
  • Public-only policy rejection of loopback.
  • Canonical IPv4-mapped IPv6 rejection.
  • Canonical IPv6 acceptance only with zero flow and scope metadata; nonzero flow or scope fails closed.
  • Compile-fail proof that a consumed plan cannot be replayed.
  • Static governance tests forbidding ToSocketAddrs, hostname-based TcpStream::connect, and proxy-environment inheritance.

Documentation and standards

  • Added ADR 0005, approved design, and implementation plan.
  • Updated README, architecture, roadmap, documentation index, CHANGELOG, repository contracts, and APA 7th doctoring.
  • Added RFC 9293 and Rust 1.97.1 TcpStream evidence.
  • Pinned the pre-existing Chromium URL canonicalizer citation to immutable revision 446d05d21720f0b3505ec21057b3e9f909784262.
  • Explicitly separates exact TCP peer proof from TLS identity, proxy/PAC authority, HTTP budgets, and Chromium socket integration.

Quality gates

The exact reviewed head must pass Rust 1.97.1 formatting, locked workspace check, all tests, strict Clippy, rustdoc with warnings denied, Security Scan, Semgrep, and exact 100% production function, line, region, and branch coverage.

Out of scope

TLS, HTTP, proxy/PAC, QUIC, Chromium, WebDriver BiDi, CDP, WebMCP, downloads, connection pooling, async-runtime integration, interface-aware scoped IPv6 authority, backoff, circuit breaking, and an end-to-end elapsed-time budget remain separately reviewable slices.

Closes #4

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 25 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e0737659-06ba-4114-b241-1e3ee0d3280a

📥 Commits

Reviewing files that changed from the base of the PR and between 9f98d43 and e587b5e.

📒 Files selected for processing (1)
  • CHANGELOG.md
📝 Walkthrough

Walkthrough

OriginWeave에 originweave-network 크레이트가 추가되었습니다. 이 크레이트는 승인된 ResolutionSnapshot과 canonical SocketAddr를 사용해 직접 TCP 연결을 수행하고, 실제 OS peer를 검증한 뒤 스트림과 연결 증거를 노출합니다.

Changes

Direct TCP peer binding

Layer / File(s) Summary
네트워크 계약과 공개 API
docs/superpowers/specs/..., docs/adr/...
단일 사용 ConnectionPlan, 주소·시간 초과·시도 제한, exact-peer 검증, credential-free evidence와 NetworkError 계약을 정의했습니다.
네트워크 크레이트와 연결 구현
Cargo.toml, crates/originweave-network/..., crates/originweave-destination/...
워크스페이스에 새 크레이트를 등록했습니다. 직접 TCP 연결, 제한된 재시도, peer 검증, 오류 체인과 공개 타입을 구현했습니다.
연결 및 정책 검증
crates/originweave-network/src/connection.rs, tests/*
가짜 connector 테스트와 loopback 통합 테스트를 추가했습니다. 입력 검증, 실패 재시도, peer 불일치, 프록시·DNS 사용 금지를 검증합니다.
구현 계획과 품질 게이트
docs/superpowers/plans/*
구현 순서, 결정적 테스트, compile-fail 검증, 문서 갱신과 품질 게이트를 기록했습니다.
아키텍처 및 전송 경계 문서
ARCHITECTURE.md, README.md, CHANGELOG.md, docs/adr/*, docs/doctoring.md, docs/product-roadmap.md, docs/README.md
직접 TCP, TLS, proxy/PAC, HTTP, Chromium의 책임 경계를 갱신했습니다. 네트워크 증거와 OS peer 검증 요구사항을 문서화했습니다.

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

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive 핵심 연결·피어 검증·정책·문서 요구사항은 반영되었지만 100% 커버리지와 모든 공개 오류의 표준 오류 계약은 요약만으로 확인할 수 없습니다. 커버리지 결과와 NetworkError의 Display, Error, 원본 I/O source 보존을 검증하는 증거를 추가하십시오.
✅ Passed checks (4 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed 변경 사항은 직접 TCP 소켓 바인딩과 관련 문서·테스트에 집중되며, TLS·HTTP·프록시 기능은 구현하지 않고 범위로만 명시합니다.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 승인된 목적지를 실제 TCP 피어에 연결하는 변경의 핵심을 정확하고 간결하게 설명합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/direct-socket-binding

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

Comment thread .github/workflows/refactor-network-connector-coverage.yml Fixed
Comment thread .github/workflows/consolidate-network-tests.yml Fixed
@seonghobae
seonghobae marked this pull request as ready for review August 6, 2026 05:03
Comment thread .github/workflows/harden-ipv6-socket-metadata.yml Fixed
Comment thread .github/workflows/harden-ipv6-socket-metadata-v2.yml Fixed
Comment thread .github/workflows/harden-ipv6-socket-metadata-v3.yml Fixed

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@seonghobae
seonghobae merged commit 9afbfee into main Aug 6, 2026
28 of 29 checks passed

@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: 8

🧹 Nitpick comments (1)
docs/superpowers/plans/2026-08-06-direct-socket-binding.md (1)

562-567: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rust 1.97.1 인용을 버전 고정 참조로 바꾸세요.

Line 564는 Rust 1.97.1을 인용하지만 stable 문서 경로를 사용합니다. Stable 문서는 이후 릴리스로 이동할 수 있으므로 현재 인용이 Rust 1.97.1의 API를 계속 증명하지 못합니다. 버전 고정 문서 또는 변경 불가능한 릴리스 참조를 사용하세요.

As per coding guidelines: “Use primary specifications, official documentation, or peer-reviewed/primary papers, and format references in APA 7th style.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-08-06-direct-socket-binding.md` around lines 562
- 567, Update the Rust TcpStream reference in the bibliography to use an
immutable Rust 1.97.1-specific documentation URL or release reference instead of
the moving stable path, while preserving the APA 7th citation format and the
existing RFC reference.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ARCHITECTURE.md`:
- Line 238: Unify the terminology in ARCHITECTURE.md by changing the line 238
reference from “persistence interfaces” to “storage interfaces,” matching the
Rust control plane boundary defined as “storage” elsewhere. If persistence is
intentionally a separate boundary, document that distinction and apply the
terminology consistently across related documentation.

In `@Cargo.toml`:
- Line 8: Update the workspace rust-version declaration in Cargo.toml from 1.97
to 1.97.1 so it matches rust-toolchain.toml, preserving originweave-network’s
inherited value.

In `@crates/originweave-network/src/connection.rs`:
- Around line 290-309: Update the documentation for ConnectionTimedOut and
ConnectionFailed to describe classification by the final bounded attempt’s error
rather than claiming every attempt had the same outcome. Add tests covering
mixed error sequences in both orders, verifying the returned variant matches the
last attempt while preserving the existing attempt count and error details.

In `@docs/doctoring.md`:
- Around line 115-116: Update the TcpStream reference URL in the cited
documentation entry to use the version-pinned Rust 1.97.1 path, replacing the
stable URL with the specified 1.97.1 URL; do not modify
docs/adr/0005-direct-socket-binding.md.

In `@docs/superpowers/plans/2026-08-06-direct-socket-binding.md`:
- Around line 455-457: Update the retry logic in the connection helper around
the downstream connection-attempt loop to retry only explicitly transient
io::ErrorKind values, while immediately returning non-retryable errors such as
PermissionDenied and InvalidInput and preserving their original cause. Define
the allowed retryable ErrorKind set and add coverage verifying non-retryable
failures do not trigger additional attempts.
- Around line 300-302: Update the connection authorization flow around
ResolutionSnapshot::authorize_connection and ConnectionPlan::new to validate the
requested port against the configured allowed-port rules, not just the IP
address. Reject mismatched nonzero ports before preserving requested_socket, and
add a failure test proving an authorized IP with a disallowed port is refused.
- Around line 503-505: Document the stale-plan contract for
ConnectionPlan::connect and add an executable test covering it. Clarify that
ResolutionSnapshot::revalidate returns a new snapshot without mutating the
original, so a plan remains valid for the authorization captured at creation
unless expiry or generation binding is introduced; if stale plans must be
rejected, bind that state to the plan and validate it in connect.

In `@docs/superpowers/specs/2026-08-06-direct-socket-binding-design.md`:
- Around line 195-197: 문서의 “Standards basis” 절에 인용한 두 1차 자료인 RFC 9293과 Rust
1.97.1 표준 라이브러리 문서에 대한 완전한 APA 7판 참고문헌을 추가하십시오. 본문 설명은 유지하고, 각 항목에 저자 또는 발행 기관,
날짜, 제목, 문서 식별자 또는 버전, URL 등 APA 7 형식에 필요한 서지 정보를 포함하십시오.

---

Nitpick comments:
In `@docs/superpowers/plans/2026-08-06-direct-socket-binding.md`:
- Around line 562-567: Update the Rust TcpStream reference in the bibliography
to use an immutable Rust 1.97.1-specific documentation URL or release reference
instead of the moving stable path, while preserving the APA 7th citation format
and the existing RFC reference.
🪄 Autofix

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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 10d081a6-c819-4316-abc9-df41dbb78c88

📥 Commits

Reviewing files that changed from the base of the PR and between 0ba39d5 and 9f98d43.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • ARCHITECTURE.md
  • CHANGELOG.md
  • Cargo.toml
  • README.md
  • crates/originweave-destination/src/resolution.rs
  • crates/originweave-destination/tests/error_contract.rs
  • crates/originweave-network/Cargo.toml
  • crates/originweave-network/src/connection.rs
  • crates/originweave-network/src/lib.rs
  • docs/README.md
  • docs/adr/0005-direct-socket-binding.md
  • docs/doctoring.md
  • docs/product-roadmap.md
  • docs/superpowers/plans/2026-08-06-direct-socket-binding.md
  • docs/superpowers/specs/2026-08-06-direct-socket-binding-design.md
  • tests/test_network_governance.py
  • tests/test_repository_contract.py

Comment thread ARCHITECTURE.md
```

No deployment mode may depend on an in-process singleton. Session, policy, destination, evidence, and persistence interfaces must remain tenant-scoped and transport-neutral.
No deployment mode may depend on an in-process singleton. Session, policy, destination, network, evidence, and persistence interfaces must remain tenant-scoped and transport-neutral.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

storagepersistence 명칭을 통일하십시오.

Line [31]은 Rust control plane 계층을 storage로 정의합니다. Line [238]은 같은 경계를 persistence interfaces로 표현합니다. 두 명칭이 같은 모듈인지 별도 경계인지 판단할 수 없습니다.

Line [238]의 persistencestorage로 변경하거나, 두 경계의 차이를 문서화하고 모든 관련 문서에서 같은 용어를 사용하십시오.

제안된 수정
-Session, policy, destination, network, evidence, and persistence interfaces must remain tenant-scoped and transport-neutral.
+Session, policy, destination, network, evidence, and storage interfaces must remain tenant-scoped and transport-neutral.

As per coding guidelines: README.mdARCHITECTURE.md는 shipped behavior와 일관되어야 합니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
No deployment mode may depend on an in-process singleton. Session, policy, destination, network, evidence, and persistence interfaces must remain tenant-scoped and transport-neutral.
No deployment mode may depend on an in-process singleton. Session, policy, destination, network, evidence, and storage interfaces must remain tenant-scoped and transport-neutral.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ARCHITECTURE.md` at line 238, Unify the terminology in ARCHITECTURE.md by
changing the line 238 reference from “persistence interfaces” to “storage
interfaces,” matching the Rust control plane boundary defined as “storage”
elsewhere. If persistence is intentionally a separate boundary, document that
distinction and apply the terminology consistently across related documentation.

Source: Coding guidelines

Comment thread Cargo.toml
"crates/originweave-resource",
"crates/originweave-evidence",
"crates/originweave-destination",
"crates/originweave-network",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import tomllib

workspace = tomllib.loads(Path("Cargo.toml").read_text(encoding="utf-8"))
toolchain = tomllib.loads(Path("rust-toolchain.toml").read_text(encoding="utf-8"))
network = tomllib.loads(
    Path("crates/originweave-network/Cargo.toml").read_text(encoding="utf-8")
)

assert workspace["workspace"]["package"]["rust-version"] == "1.97.1"
assert toolchain["toolchain"]["channel"] == "1.97.1"
assert network["package"]["rust-version"]["workspace"] is True
PY

Repository: ContextualWisdomLab/OriginWeave

Length of output: 289


🏁 Script executed:

set -euo pipefail

printf '%s\n' '--- Cargo.toml ---'
sed -n '1,35p' Cargo.toml

printf '%s\n' '--- rust-toolchain.toml ---'
cat rust-toolchain.toml

printf '%s\n' '--- network crate manifest ---'
sed -n '1,30p' crates/originweave-network/Cargo.toml

printf '%s\n' '--- relevant declarations ---'
rg -n 'rust-version|channel|originweave-network' Cargo.toml rust-toolchain.toml crates/originweave-network/Cargo.toml

Repository: ContextualWisdomLab/OriginWeave

Length of output: 1852


지원 Rust 최소 버전을 1.97.1로 일치시키십시오.

Cargo.toml은 현재 rust-version = "1.97"을 선언하고, rust-toolchain.toml1.97.1을 사용합니다. workspace rust-version1.97.1로 변경하십시오. originweave-network는 이 값을 상속합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Cargo.toml` at line 8, Update the workspace rust-version declaration in
Cargo.toml from 1.97 to 1.97.1 so it matches rust-toolchain.toml, preserving
originweave-network’s inherited value.

Source: Coding guidelines

Comment on lines +290 to +309
/// Every bounded attempt ended with a timeout error.
ConnectionTimedOut {
/// The exact socket address submitted to the operating system.
socket_address: SocketAddr,
/// The number of attempts that completed before failure.
attempt_count: u8,
/// The timeout applied to each attempt.
connect_timeout: Duration,
/// The final operating-system error.
source: io::Error,
},
/// Every bounded attempt ended with a non-timeout connection error.
ConnectionFailed {
/// The exact socket address submitted to the operating system.
socket_address: SocketAddr,
/// The number of attempts that completed before failure.
attempt_count: u8,
/// The final operating-system error.
source: io::Error,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

오류 변형의 문서를 실제 분류 규칙과 일치시키십시오.

현재 [ConnectionRefused, TimedOut] 시퀀스는 ConnectionTimedOut을 반환합니다. 첫 번째 시도는 timeout이 아니므로 “Every bounded attempt” 설명은 사실이 아닙니다. 반대 순서도 같은 문제를 갖습니다. 문서를 마지막 bounded attempt의 오류로 수정하고 혼합 오류 시퀀스 테스트를 추가하십시오.

수정 예시
-    /// Every bounded attempt ended with a timeout error.
+    /// The final bounded attempt ended with a timeout error.
@@
-    /// Every bounded attempt ended with a non-timeout connection error.
+    /// The final bounded attempt ended with a non-timeout connection error.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// Every bounded attempt ended with a timeout error.
ConnectionTimedOut {
/// The exact socket address submitted to the operating system.
socket_address: SocketAddr,
/// The number of attempts that completed before failure.
attempt_count: u8,
/// The timeout applied to each attempt.
connect_timeout: Duration,
/// The final operating-system error.
source: io::Error,
},
/// Every bounded attempt ended with a non-timeout connection error.
ConnectionFailed {
/// The exact socket address submitted to the operating system.
socket_address: SocketAddr,
/// The number of attempts that completed before failure.
attempt_count: u8,
/// The final operating-system error.
source: io::Error,
},
/// The final bounded attempt ended with a timeout error.
ConnectionTimedOut {
/// The exact socket address submitted to the operating system.
socket_address: SocketAddr,
/// The number of attempts that completed before failure.
attempt_count: u8,
/// The timeout applied to each attempt.
connect_timeout: Duration,
/// The final operating-system error.
source: io::Error,
},
/// The final bounded attempt ended with a non-timeout connection error.
ConnectionFailed {
/// The exact socket address submitted to the operating system.
socket_address: SocketAddr,
/// The number of attempts that completed before failure.
attempt_count: u8,
/// The final operating-system error.
source: io::Error,
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/originweave-network/src/connection.rs` around lines 290 - 309, Update
the documentation for ConnectionTimedOut and ConnectionFailed to describe
classification by the final bounded attempt’s error rather than claiming every
attempt had the same outcome. Add tests covering mixed error sequences in both
orders, verifying the returned variant matches the last attempt while preserving
the existing attempt count and error details.

Source: Coding guidelines

Comment thread docs/doctoring.md
Comment on lines +115 to +116
The Rust Project Developers. (2026). *TcpStream in std::net* (Rust 1.97.1) [Software documentation]. https://doc.rust-lang.org/stable/std/net/struct.TcpStream.html

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n 'Rust 1\.97\.1|doc\.rust-lang\.org/(stable|1\.97\.1)' \
  docs/doctoring.md docs/adr/0005-direct-socket-binding.md README.md

curl -fsSL -o /dev/null \
  https://doc.rust-lang.org/1.97.1/std/net/struct.TcpStream.html

Repository: ContextualWisdomLab/OriginWeave

Length of output: 2441


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- docs/doctoring.md ---'
sed -n '104,118p' docs/doctoring.md

printf '%s\n' '--- docs/adr/0005-direct-socket-binding.md ---'
sed -n '108,120p' docs/adr/0005-direct-socket-binding.md

printf '%s\n' '--- Rust documentation URL comparison ---'
for url in \
  'https://doc.rust-lang.org/stable/std/net/struct.TcpStream.html' \
  'https://doc.rust-lang.org/1.97.1/std/net/struct.TcpStream.html'; do
  echo "$url"
  curl -fsSL "$url" |
    tr '\n' ' ' |
    sed -n 's/.*<title>\([^<]*\)<\/title>.*/\1/p'
  curl -fsSI "$url" | sed -n '1p;/^location:/Ip'
done

Repository: ContextualWisdomLab/OriginWeave

Length of output: 2224


Rust 1.97.1 출처 URL을 버전 경로로 고정하십시오.

docs/doctoring.md:115의 URL을 https://doc.rust-lang.org/1.97.1/std/net/struct.TcpStream.html로 변경하십시오. docs/adr/0005-direct-socket-binding.md에는 해당 URL이 없으므로 수정 대상이 아닙니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/doctoring.md` around lines 115 - 116, Update the TcpStream reference URL
in the cited documentation entry to use the version-pinned Rust 1.97.1 path,
replacing the stable URL with the specified 1.97.1 URL; do not modify
docs/adr/0005-direct-socket-binding.md.

Source: Coding guidelines

Comment on lines +300 to +302
**Interfaces:**
- Consumes: `ResolutionSnapshot::authorize_connection(IpAddr)` and `ConnectionEvidence` accessors.
- Produces: validated `ConnectionPlan` with private origin, requested socket, address class, timeout, and attempt bound.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -u
# IP 승인과 포트 승인을 함께 검사합니다.
rg -n -C 8 'authorize_connection|requested_socket|SocketAddr|port' \
  crates/originweave-destination crates/originweave-network

Repository: ContextualWisdomLab/OriginWeave

Length of output: 50387


Authorization Bypass (CWE-863): Incorrect Authorization

Exploitability: Moderate

요청 포트를 승인 범위에 포함하세요.

ResolutionSnapshot::authorize_connection(IpAddr)는 IP만 검사합니다. ConnectionPlan::new는 포트 0만 거부하고 임의의 비영 포트를 requested_socket에 보존합니다. 이후 connect_timeout은 전체 주소를 사용합니다. 승인된 IP에 승인되지 않은 포트를 지정할 수 있습니다. 허용 포트 규칙과 불일치 포트를 거부하는 실패 테스트를 추가하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-08-06-direct-socket-binding.md` around lines 300
- 302, Update the connection authorization flow around
ResolutionSnapshot::authorize_connection and ConnectionPlan::new to validate the
requested port against the configured allowed-port rules, not just the IP
address. Reject mismatched nonzero ports before preserving requested_socket, and
add a failure test proving an authorized IP with a disallowed port is refused.

Comment on lines +455 to +457
- [ ] **Step 2: Implement retry, exact peer verification, evidence, and stream exposure**

The private generic helper returns `(Stream, SocketConnectionEvidence)`. The public method wraps the system stream in `DirectTcpConnection` only after exact equality.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

재시도 가능한 오류를 명시적으로 제한하세요.

현재 downstream crates/originweave-network/src/connection.rs의 Line 132-149는 마지막 시도가 아니면 모든 io::Error를 재시도합니다. PermissionDenied 또는 InvalidInput 같은 비일시적 오류도 추가 연결을 수행하고, 중간 오류 원인은 버립니다. 30초 timeout과 4회 시도 조합은 최대 120초를 사용할 수 있습니다. 재시도 가능한 ErrorKind 목록을 정의하고, 비재시도 오류의 호출 횟수를 테스트하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-08-06-direct-socket-binding.md` around lines 455
- 457, Update the retry logic in the connection helper around the downstream
connection-attempt loop to retry only explicitly transient io::ErrorKind values,
while immediately returning non-retryable errors such as PermissionDenied and
InvalidInput and preserving their original cause. Define the allowed retryable
ErrorKind set and add coverage verifying non-retryable failures do not trigger
additional attempts.

Comment on lines +503 to +505
- [ ] **Step 3: Add a compile-fail doctest for single use**

Document `ConnectionPlan::connect` with a `compile_fail` example that tries to call `connect` twice on the same value and fails because the first call moved the plan.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -u
# snapshot 수명과 plan 재검증 계약을 확인합니다.
rg -n -C 8 'ResolutionSnapshot|authorize_connection|expires|generation|stale' \
  crates/originweave-destination crates/originweave-network

Repository: ContextualWisdomLab/OriginWeave

Length of output: 37756


🏁 Script executed:

#!/usr/bin/env bash
set -u
printf '%s\n' '--- resolution semantics ---'
sed -n '151,235p' crates/originweave-destination/src/resolution.rs
printf '%s\n' '--- stale-plan references ---'
rg -n -C 6 'stale.plan|stale.plan|stale|Issue `#4`|issue.?4|revalidat|generation|expir|single.use' \
  docs/superpowers/plans/2026-08-06-direct-socket-binding.md \
  crates/originweave-destination crates/originweave-network

Repository: ContextualWisdomLab/OriginWeave

Length of output: 15308


🏁 Script executed:

#!/usr/bin/env bash
set -u
printf '%s\n' '--- full revalidation contract ---'
sed -n '228,275p' crates/originweave-destination/src/resolution.rs
printf '%s\n' '--- plan requirements and snapshot wording ---'
rg -n -C 8 'ResolutionSnapshot|single-use|stale|revalidat|Issue 4|`#4`|expiry|generation|revok' \
  docs/superpowers/plans/2026-08-06-direct-socket-binding.md \
  docs crates 2>/dev/null

Repository: ContextualWisdomLab/OriginWeave

Length of output: 50390


Stale Authorization Plan (CWE-863): Incorrect Authorization

stale-plan 계약을 명시하고 실행 가능한 테스트를 추가하세요.

ResolutionSnapshot::revalidate는 기존 snapshot을 변경하지 않고 새 snapshot을 반환합니다. 따라서 현재 API에는 만료, 폐기 또는 generation 의미가 없습니다. plan이 생성 시 캡처한 승인으로 수명 동안 유효하다면 이 계약과 허용되는 TOCTOU 범위를 문서화하세요. stale plan을 거부해야 한다면 expiry 또는 generation을 plan에 바인딩하고 connect에서 검사하세요. Issue #4 완료 조건에 해당 테스트를 추가하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-08-06-direct-socket-binding.md` around lines 503
- 505, Document the stale-plan contract for ConnectionPlan::connect and add an
executable test covering it. Clarify that ResolutionSnapshot::revalidate returns
a new snapshot without mutating the original, so a plan remains valid for the
authorization captured at creation unless expiry or generation binding is
introduced; if stale plans must be rejected, bind that state to the plan and
validate it in connect.

Comment on lines +195 to +197
## Standards basis

RFC 9293 defines a TCP connection by its local and remote socket pair and consolidates the current Standards Track TCP specification. Rust 1.97.1 documents that `TcpStream::connect_timeout` takes one `SocketAddr`, applies the timeout to that individual address, and uses an operating-system-specific nonblocking connection mechanism; `peer_addr` returns the remote peer socket address. These properties make the API appropriate for a no-reresolution, exact-peer adapter.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

APA 7th 형식의 참고문헌을 추가하십시오.

이 절은 RFC 9293 및 Rust 표준 라이브러리 문서를 설계 근거로 사용합니다. 그러나 APA 7th 형식의 참고문헌이 없습니다. 두 1차 자료의 완전한 참고문헌을 추가하십시오.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/specs/2026-08-06-direct-socket-binding-design.md` around
lines 195 - 197, 문서의 “Standards basis” 절에 인용한 두 1차 자료인 RFC 9293과 Rust 1.97.1 표준
라이브러리 문서에 대한 완전한 APA 7판 참고문헌을 추가하십시오. 본문 설명은 유지하고, 각 항목에 저자 또는 발행 기관, 날짜, 제목, 문서
식별자 또는 버전, URL 등 APA 7 형식에 필요한 서지 정보를 포함하십시오.

Source: Coding guidelines

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.

[Product Gap] Bind approved destination snapshots to actual socket connections

2 participants