Skip to content

feat(api): consolidate export idempotency lookup and quarantine-parity adapters - #466

Draft
seonghobae wants to merge 24 commits into
feat/export-retrieval-get-gap-003afrom
feat/export-idempotency-lookup-cli-gap-003a
Draft

feat(api): consolidate export idempotency lookup and quarantine-parity adapters#466
seonghobae wants to merge 24 commits into
feat/export-retrieval-get-gap-003afrom
feat/export-idempotency-lookup-cli-gap-003a

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Consolidated Analysis Run / export lookup landing vehicle

This Draft is the surviving naruon-facing Analysis Run / export lookup application-adapter vehicle. It folds strict-ancestor one-operation PRs instead of keeping them as parallel WIP. #465 was folded first, #471 was folded after its cross-tenant disclosure defect was repaired and quarantined, and #474 has now been fast-forward folded after verifying #466@12e8337d68d3263feab21c63cf66a8578e997d07 was exactly #474's merge base and #474 was two commits ahead with no divergence. #465/#471/#474 remain immutable review and RED/GREEN history; their source is preserved on this branch.

Preserved metric-free lookup behavior

  • GET /v1/exports/by-idempotency/{idempotency_key} dispatches before GET-by-id so the route prefix is not parsed as a server-assigned export_id;
  • lookup is naruon-only; LineageWeave and unpublished consumers fail closed;
  • zero or multiple matches fail closed without a tenant oracle;
  • metric/scientific-acceptance fields are recursively refused;
  • tepp-export-lookup lookup exposes only the metric-free identity (export_id, decision_code, idempotency_key);
  • opaque idempotency keys accepted by authorization remain addressable: slash is percent-encoded as data and literal by-idempotency remains valid data after the route prefix.

Stored-request-by-idempotency quarantine

The first stored-request GET implementation searched Naruon tenant namespaces using consumer + client key and could serialize tenant_workspace_id and principal_id without authenticated tenant/principal scope. This vehicle therefore keeps GET /v1/exports/by-idempotency/{idempotency_key}/request quarantined until a versioned authenticated tenant-and-principal authority binding exists and proves cross-tenant/cross-principal denial. An idempotency key is replay identity, never a bearer credential.

The folded #474 CLI is quarantine parity, not disclosure: tepp-export-lookup-request get validates its local inputs and calls the typed exchange builder, which returns authorization_denied; it does not print the stored authorization request or tenant/principal identity. This preserves fail-closed behavior instead of creating a separate supported route.

DDD / queue authority

These GET/CLI mechanics are adapters inside the Analysis Run application context, not bounded contexts. Operation-specific ADR 0093/0094/0099/0100 records are implementation lineage pending repository-wide normalization under #437; one route, refusal, or CLI verb does not create architecture authority. Further compatible export-lookup mechanics must fold here or into a coherent successor rather than mint another micro-PR.

Reusable psychometric arithmetic remains outside this adapter. HTTP success/failure is never ADR 0014 scientific acceptance. NaruonLiveService stays POST-only.

Current exact head: 71f34b890bbd096eee152947c5e22d9778d323e8.

Merge gate

The latest fold invalidates predecessor-head hosted evidence as landing authority. Reacquire fresh exact-head Rust/documentation/security/SAST and 100% owned production line/branch coverage, re-fetch current reviews/threads, and obtain qualifying independent current-head approval under live organization rules. Keep the stored-request-by-idempotency resource quarantined unless authenticated scope is implemented and tested. No predecessor-head evidence transfer, force push, fail-open change, self-approval, or routine protection bypass.

GAP-003A unique slice: AnalysisRunLiveService serves naruon-only
GET /v1/exports/by-idempotency/{idempotency_key} as a metric-free
export_id lookup. NaruonLiveService stays POST-only. ADR 0093.
Publish tepp-export-lookup lookup so operators can resolve a 200 naruon
export authorization receipt to export_id on spawned tepp-loopback TCP
without writing raw HTTP. Metric-free identity stdout. Empty stdin
admitted. LineageWeave refused. NaruonLiveService stays POST-only.
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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.

@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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 3 potential issues.

Devin Review

Comment thread crates/tepp_api/src/export_idempotency_lookup_cli.rs
Comment thread crates/tepp_api/src/export_idempotency_lookup_cli.rs
Comment thread crates/tepp_api/src/export_idempotency_lookup_cli.rs
@seonghobae seonghobae added the enhancement New feature or request label Sep 1, 2026 — with ChatGPT Codex Connector
@seonghobae seonghobae changed the title feat(api): mint export idempotency-lookup GET from a dedicated CLI feat(api): consolidate export idempotency lookup GET and CLI Sep 1, 2026
@seonghobae
seonghobae changed the base branch from feat/export-idempotency-lookup-get-gap-003a to feat/export-retrieval-get-gap-003a September 1, 2026 16:02

@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 3 new potential issues.

Devin Review

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Current-head coverage remains unverified

Repository rules require 100% production line and branch coverage. Confirm current-head coverage for the new route, DTO, transport parser, and CLI branches.

Devin Review

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

Comment thread crates/tepp_api/src/export_idempotency_lookup_cli.rs Outdated
Comment thread crates/tepp_api/src/export_idempotency_lookup_http.rs Outdated
Publish GET /v1/exports/by-idempotency/{idempotency_key}/request so
operators who hold a 200 authorization receipt can recover the stored
create without a second hop through export_id stored-request.
Metric-free. Zero and ambiguous matches fail closed. LineageWeave
refused. NaruonLiveService stays POST-only.
Module and compose docs no longer promise stored-create stdout. The
typed exchange remains authorization_denied after origin/key validation.
@seonghobae seonghobae changed the title feat(api): consolidate export idempotency lookup GET and CLI feat(api): consolidate export idempotency lookup and quarantine-parity adapters Sep 1, 2026

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Exact-head COMMENT on 71f34b890bbd096eee152947c5e22d9778d323e8 (not APPROVE; author COMMENT is not an independent approval under ruleset 18156473). Predecessor Checks/reviews do not transfer. Do not un-draft. Do not unstack onto main. Do not add GET to NaruonLiveService.

Fail-closed read at this SHA:

  • naruon_export_idempotency_lookup_stored_request_exchange validates origin/key syntax (slash, NUL, reserved by-idempotency prefix, max length) then returns ApiError::AuthorizationDenied without minting a disclosure exchange (export_idempotency_lookup_stored_request_http.rs).
  • FORBIDDEN_STORED_REQUEST_KEYS includes tenant_workspace_id and principal_id plus scientific/terminal keys.
  • tepp-export-lookup-request documents that compose stays quarantined and never prints a stored export-authorization request; CLI contract compose_stays_quarantined_and_never_discloses_stored_create asserts AuthorizationDenied even after a matching POST exists.
  • LineageWeave consumer and non-loopback hosts fail closed in from_args.

Keep ADR 0099 quarantine. An idempotency key is replay identity, not a bearer credential. Reactivation still requires a versioned authenticated tenant-and-principal binding plus proven cross-tenant/cross-principal denial. Do not un-quarantine stored-request-by-client-key disclosure. Unique tepp-export-lookup / tepp-export-lookup-request plus ADR 0093+0094+0099+0100 remain occupied here (folded #465/#471/#474). mergeable_state=unstable — not merge-ready.

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant