Skip to content

feat(api): admit LineageWeave as a modular analysis-run consumer - #155

Merged
seonghobae merged 114 commits into
mainfrom
feat/lineageweave-live-consumer-contract
Aug 24, 2026
Merged

feat(api): admit LineageWeave as a modular analysis-run consumer#155
seonghobae merged 114 commits into
mainfrom
feat/lineageweave-live-consumer-contract

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Stack

Root cause

The #107 listener accepted only tepp-consumer: naruon. A structurally valid LineageWeave AnalysisRunRequest therefore failed closed with HTTP 400. The listener also keyed idempotency by tenant plus caller key only, allowing two modular consumers to collide when they reused a legitimate tenant/key pair.

Fix

  • publish LINEAGEWEAVE_CONSUMER_CODE and NARUON_CONSUMER_CODE;
  • add a credential-free lineageweave_analysis_run_exchange builder;
  • add a consumer-neutral AnalysisRunLiveService for the shared /v1/analysis-runs boundary;
  • isolate accepted-run idempotency by consumer + tenant + caller key;
  • keep unknown consumers, credential headers, non-loopback hosts, malformed bodies, changed replays, and oversized requests fail-closed;
  • preserve the existing Naruon listener as a compatibility surface;
  • record the authority, security, recovery, migration, and scientific-claim boundaries in ADR 0017.

TDD evidence

The first commit added a failing contract test because the LineageWeave symbols and consumer admission were absent. The GREEN implementation verifies:

  • LineageWeave receives HTTP 202 AnalysisRunAccepted;
  • the exchange forwards no credentials;
  • Naruon and LineageWeave cannot replay each other's accepted runs;
  • same-consumer semantically identical replays remain idempotent;
  • a changed payload under the same consumer/tenant/key is rejected;
  • unpublished consumers, hostile framing, credential headers, and non-loopback hosts are rejected.

Claim boundary

  • This is an accepted transport acknowledgement only; it does not invent theta, uncertainty, convergence, validity, or a completed psychometric result.
  • Loopback HTTP remains feat(api): serve naruon POSTs on loopback with a live deadline #107's scope. Production TLS and deployment remain separate work.
  • No shared database, table access, browser token, reviewer credential, or provider credential is introduced.

Current exact state

  • Base: main@c45be17a9dbce95ef81cee230e9d128abc7160ac
  • Head: 17f06e814e943ebd9bf592549e2d218a4efed112
  • The obsolete write-capable one-shot workflow is absent from the current tree; its outdated security thread has been resolved.
  • Retargeting to main changes no product intent and prevents this PR from landing only on the already-merged feat(api): serve naruon POSTs on loopback with a live deadline #107 feature branch.

Merge gate

  • Exact-current-head Rust Foundation CI, Documentation Quality, security, SAST, dependency, coverage, rustdoc, and repository-contract gates must be terminal-success.
  • Review threads must be re-fetched after the head settles.
  • A qualifying independent exact-head approval is required.
  • Do not self-approve, force-merge, bypass protection, or transfer evidence from feat(api): project LineageWeave evidence into cutoff-safe histories #159 or an earlier head.

Open in Devin Review

Summary by CodeRabbit

  • 새 기능

    • 소비자별 분석 실행 API 진입 경로를 추가했습니다.
    • LineageWeave용 temporal-context API를 제공하며, 지식 기준 시점에 따른 이벤트 정렬과 관계를 반환합니다.
    • 프로젝트 이력 조회 및 결정론적 투영 API를 추가했습니다.
    • 로컬 루프백 환경에서 실행 가능한 서비스와 컨테이너를 제공합니다.
    • 요청 재시도와 중복·충돌을 소비자 및 작업 공간별로 안전하게 처리합니다.
  • 보안 및 안정성 개선

    • 요청·응답에 256 KiB 크기 제한을 적용하고 초과 데이터를 거부합니다.
    • 인증 정보, 비루프백 호스트, 잘못된 시간과 페이로드를 차단합니다.
  • 문서 및 품질

    • API 계약과 아키텍처 문서를 업데이트했습니다.
    • 커버리지 검증과 진단 도구를 개선했습니다.

cursoragent and others added 2 commits August 16, 2026 16:13
PR #87 accepted analysis-run bodies with knowledge_cutoff "k" and hung
when a client sent a partial request. The named live listener now
installs a read/write deadline, requires a loopback Host, refuses
Transfer-Encoding and NIM/proxy headers, parses RFC 3339 cutoffs,
keys idempotency by tenant plus key, and proves export over TCP.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
The live TEPP listener currently accepts only tepp-consumer: naruon and
keys idempotency without the consumer identity. These regressions require a
credential-free LineageWeave exchange, a published consumer code, accepted
202 handling, cross-consumer idempotency isolation, and fail-closed unknown
consumers.
@coderabbitai

coderabbitai Bot commented Aug 19, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

루프백 HTTP ingress를 공통화했습니다. Naruon과 LineageWeave의 분석 실행, temporal-context 및 project-history 계약을 추가했습니다. 소비자별 replay, cutoff 검증, 결정적 projection 및 wire-size 제한을 적용했습니다. Coverage CI와 tepp-loopback 패키징을 갱신했습니다.

Changes

소비자 범위 ingress와 계약

Layer / File(s) Summary
공통 HTTP ingress와 라이브 서비스
crates/tepp_api/src/live_http.rs, crates/tepp_api/src/naruon_live.rs, crates/tepp_api/src/naruon_http.rs, crates/tepp_api/src/analysis_run_live.rs, crates/tepp_api/tests/example_contracts.rs
HTTP 프레이밍, 헤더, loopback 호스트, 본문 크기 제한 및 오류 처리를 공통화했습니다. 분석 실행 수락, replay 및 충돌 처리를 유지했습니다.
Temporal-context 계약과 결과 생성
crates/tepp_api/src/temporal_context.rs, crates/tepp_api/src/lib.rs, crates/tepp_api/tests/lineageweave_temporal_context_contract.rs, docs/API_CONTRACT.md
Temporal-context DTO, cutoff 검증, 이벤트 정렬, 관계와 전환 간극 생성을 추가했습니다. 공개 API와 HTTP 계약을 갱신했습니다.
Project-history 계약과 결정적 projection
crates/tepp_api/src/project_history.rs, crates/tepp_api/tests/lineageweave_project_history_contract.rs, docs/adr/0018-project-history-wire-size-symmetry.md, docs/adr/0019-lineageweave-project-history-boundary.md
Project-history DTO, RFC 3339 검증, 결정적 이벤트 정렬, finding 재계산, HTTPS 교환 및 projection 검증을 추가했습니다.
LineageWeave 교환과 소비자별 replay
crates/tepp_api/src/lineageweave_http.rs, crates/tepp_api/src/analysis_run_live.rs, crates/tepp_api/src/lib.rs, crates/tepp_api/tests/lineageweave_http_contract.rs
LineageWeave용 HTTPS 교환과 project-history route를 추가했습니다. consumer·tenant·idempotency key별 replay와 충돌 처리를 구현했습니다.
Loopback 실행 패키징과 계약 문서
crates/tepp_api/src/bin/tepp_loopback.rs, crates/tepp_api/Cargo.toml, Dockerfile, docs/ADR*, docs/API_CONTRACT.md, docs/verification/*, CHANGELOG*
tepp-loopback 바이너리와 Docker 실행 구성을 추가했습니다. ADR, API 계약, 검증 문서 및 변경 기록을 갱신했습니다.
공통 JSON wire-size 제한
crates/tepp_api/src/wire.rs
제한 writer와 to_json_with_limit을 추가했습니다. 제한 초과를 ApiError::LimitExceeded로 반환합니다.

브랜치 커버리지 검증

Layer / File(s) Summary
브랜치 데이터 검증과 CI 명령
scripts/check_coverage.py, tests/quality/test_check_coverage.py, .github/workflows/ci.yml, .github/workflows/hourly-nim-product-development.yml, tests/quality/test_ci_coverage_diagnostics.py, tests/quality/test_hourly_nim_product_development.py, docs/research/rust-quality-tooling.md
파일별 branch 결과를 좌표 기준으로 병합합니다. malformed 입력과 비실행 Rust 라인을 검증합니다. Rust nightly를 2026-08-21로 변경하고 coverage 명령을 갱신했습니다.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant LineageWeave
  participant AnalysisRunLiveService
  participant live_http
  participant project_history_projection
  LineageWeave->>AnalysisRunLiveService: /v1/project-history POST 요청 전송
  AnalysisRunLiveService->>live_http: HTTP 프레이밍과 공통 헤더 검증 요청
  live_http-->>AnalysisRunLiveService: 검증된 UTF-8 본문 반환
  AnalysisRunLiveService->>project_history_projection: 검증된 ProjectHistoryRequest 전달
  project_history_projection-->>AnalysisRunLiveService: 결정적 ProjectHistoryProjection 반환
  AnalysisRunLiveService-->>LineageWeave: 200 응답과 projection JSON 반환
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.45% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 94 functions across 15 files. (7 skipped: 7 unsupported.) 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 제목은 LineageWeave를 모듈형 analysis-run 소비자로 추가하는 PR의 핵심 변경을 명확하고 간결하게 설명합니다.
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.
✨ 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/lineageweave-live-consumer-contract

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.

seonghobae and others added 4 commits August 19, 2026 16:06
Publish a credential-free LineageWeave analysis-run exchange and a
consumer-neutral loopback ingress. Accepted-run idempotency is isolated by
consumer, tenant, and caller key; unpublished consumers and hostile headers
fail closed. The acknowledgement remains asynchronous and does not claim a
completed psychometric result.
The one-shot workflow removes test-only imports from production code, runs the pinned Rust formatter, verifies formatting, commits the repair, and removes itself.
@seonghobae
seonghobae marked this pull request as ready for review August 20, 2026 02:45
@seonghobae
seonghobae marked this pull request as draft August 20, 2026 03:13
@seonghobae
seonghobae marked this pull request as ready for review August 20, 2026 03:14
@seonghobae
seonghobae enabled auto-merge (squash) August 24, 2026 04:04
@opencode-agent
opencode-agent Bot disabled auto-merge August 24, 2026 04:35
@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact-head Strix disposition

The exact-head strix check is annotated STRIX_PROVIDER_UNAVAILABLE; the annotation names provider/backend unavailability and contains no source finding. This is not treated as a passed security result, and no source change or fake status is being introduced. Re-evaluate after Strix can produce a valid exact-head result; protected merge remains withheld until then and until the required independent approvals exist.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact-head review disposition

  • Exact head: 2071a9c0090a24cd6583147f69c89020cda006ed; base: c45be17a9dbce95ef81cee230e9d128abc7160ac.
  • The LineageWeave consumer boundary, consumer-scoped replay/idempotency, loopback validation, wire limits, deterministic projection, and coverage contracts were reviewed against the current tree. No new actionable source change is justified from the paused predecessor-head review.
  • Current required checks are successful except strix, which remains queued; no hosted success is claimed for that gate.
  • No qualifying independent approval is present. Decision: WAIT_AND_REMEDIATE; this ordinary modular feature is not a guarded-force-merge candidate.

Scorecard Pinned-Dependencies flags rust:1.97.1-bookworm as unpinned.
Pin the multi-arch index digest verified against Docker Hub
(sha256:0e2bcaef...e42e4a97) so the build stage matches the pinned
runtime stage policy.
@seonghobae
seonghobae enabled auto-merge August 24, 2026 06:21
@github-actions
github-actions Bot disabled auto-merge August 24, 2026 08:20
@seonghobae

Copy link
Copy Markdown
Contributor Author

Exact-head restack and verification note

  • Exact head: 849a1af69c67e32745e3618adc2353c98ce40adf
  • Exact base: 3aa634af217938539891d81d8cd48de081e6491b
  • Local merge-result tree against the then-current protected main was conflict-free before the latest main movement; the branch was subsequently restacked normally through main temporal gate fixes.
  • The temporal-context response-size finding is resolved in this exact source: TemporalContextResponse::to_json uses bounded serialization and the contract test temporal_context_serialization_enforces_the_shared_wire_limit asserts ApiError::LimitExceeded for oversized responses.
  • The latest normal restack also preserves main temporal clock fixes, unique ADR numbering (0017 hourly gateway, 0018 consumer ingress, 0019 wire symmetry, 0020 LineageWeave boundary), and the dynamic documentation crate inventory.
  • Local checks on the merged tree: Rust 1.97.1 workspace tests passed; Clippy with -D warnings passed; documentation validation passed; Python quality tests passed; line coverage passed 4245/4245; pinned nightly branch coverage passed 1596/1596; git diff --check passed.
  • Current hosted checks and independent review are still pending. Decision remains WAIT_AND_REMEDIATE; this ordinary product/ecosystem PR does not meet any guarded-force deadlock classification.

# Conflicts:
#	CHANGELOG.md
#	docs/adr/0002-six-clock-temporal-semantics.md

@devin-ai-integration devin-ai-integration 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.

Devin Review found 1 new potential issue.

Open in Devin Review

Comment on lines +223 to +230
if let Some((stored_request, stored_projection)) =
self.accepted_project_histories.get(&replay_key)
{
if stored_request == &request {
return Ok(json_response(200, "OK", stored_projection.to_json()?));
}
return Err(ApiError::InvalidWirePayload);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Project-history replay uses exact struct equality

accept_project_history compares stored vs new with stored_request == &request (full PartialEq, including event order), while accept_analysis_run uses requests_are_idempotent_matches. A retry that reorders the events array under the same idempotency key is treated as a conflict (400) rather than an idempotent replay. Possibly intentional, but stricter than the analysis-run path.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

# Conflicts:
#	CHANGELOG.md
#	docs/adr/0002-six-clock-temporal-semantics.md
#	docs/adr/0003-relational-event-multiple-membership.md

@devin-ai-integration devin-ai-integration 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.

Devin Review found 2 new potential issues.

Open in Devin Review

Comment thread docs/TRACEABILITY.md
Comment on lines +24 to +25
| versioned service/API contracts and exports | PRD; API contract; ADR 0011/0013 | `tepp_api` analysis-run/export/JSON-LD/GraphML contracts on protected main (PR #21); merged PR #158 supplies the LineageWeave cutoff-safe temporal-context DTO and PR #155 carries its current loopback consumer boundary; production TLS remaining | partial |
| immutable split/run/reproducibility manifests | ADR 0013; ERD | `tepp_api` reproducibility manifest and corpus-split leakage-audit wire (`CorpusSplitManifest` v1) on the active stack; `persistence_postgres` append-only SQL insert/lookup for `reproducibility_manifest`, `corpus_split_manifest`, `model_run`, and `model_artifact` (migration `0003`); full physical ERD constraints remaining | partial |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Duplicate rows added to traceability matrix

Two capabilities now appear twice in the matrix: 'versioned service/API contracts and exports' and 'immutable split/run/reproducibility manifests'. The new rows duplicate existing ones, a likely restack artifact that no documentation validator catches.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +84 to +89
International Organization for Standardization. (2019). *Date and time—Representations for information interchange—Part 1: Basic rules* (ISO Standard No. 8601-1:2019). https://www.iso.org/standard/70907.html
`temporal_core` owns the thirteen elementary relations and composition;
`prediction_contradiction` uses `before`/`after` as contradiction,
`meets`/`met_by` as unsupported adjacency, and
`during`/`starts`/`finishes`/`equals` as the only coverage relations that can
authorize promotion.

@devin-ai-integration devin-ai-integration Bot Aug 24, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Prose and duplicate citation spliced into references

The insertion places implementation prose between APA reference entries and re-adds an Allen (1983) citation that already exists earlier in the file, reading like a merge artifact rather than a clean reference addition.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

# Conflicts:
#	CHANGELOG.md
#	docs/adr/0002-six-clock-temporal-semantics.md
#	docs/adr/0003-relational-event-multiple-membership.md
#	docs/research/standards-and-literature.md
# Conflicts:
#	CHANGELOG.md
#	docs/adr/0002-six-clock-temporal-semantics.md
#	docs/adr/0003-relational-event-multiple-membership.md
#	docs/research/standards-and-literature.md
# Conflicts:
#	CHANGELOG.md
#	docs/adr/0003-relational-event-multiple-membership.md
#	docs/research/standards-and-literature.md
# Conflicts:
#	CHANGELOG.md
#	docs/adr/0012-temporal-relational-shared-latent-topic-measurement.md
# Conflicts:
#	CHANGELOG.md
#	docs/adr/0012-temporal-relational-shared-latent-topic-measurement.md
# Conflicts:
#	CHANGELOG.md
#	docs/adr/0012-temporal-relational-shared-latent-topic-measurement.md
# Conflicts:
#	CHANGELOG.md
#	docs/adr/0012-temporal-relational-shared-latent-topic-measurement.md
…e-consumer-contract

# Conflicts:
#	CHANGELOG.md
#	docs/adr/0003-relational-event-multiple-membership.md
#	docs/adr/0012-temporal-relational-shared-latent-topic-measurement.md
#	tests/quality/test_check_docstrings.py
@seonghobae
seonghobae merged commit 1113f86 into main Aug 24, 2026
23 of 26 checks passed
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: critical

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants