Skip to content

feat(api): consolidate project-history stored-request GET and CLI - #456

Draft
seonghobae wants to merge 4 commits into
feat/project-history-retrieval-get-gap-003afrom
feat/project-history-stored-request-cli-gap-003a
Draft

feat(api): consolidate project-history stored-request GET and CLI#456
seonghobae wants to merge 4 commits into
feat/project-history-retrieval-get-gap-003afrom
feat/project-history-stored-request-cli-gap-003a

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Consolidated landing vehicle

This PR is the surviving LineageWeave-facing Analysis Run / project-history application-adapter vehicle. It now folds predecessor #455 and the unique project-history query-CLI behavior from #420 into one source lineage instead of leaving one-operation micro-PRs as independent product candidates.

Preserved source/test evidence

DDD / WIP disposition

This is one Analysis Run adapter landing vehicle, not a new bounded context. After exact-head source verification demonstrates the #420 behavior is present here, #420 may close as superseded_by_fold; its discussion remains historical evidence. Further project-history HTTP/CLI one-operation slices should fold here or into a deliberate successor rather than creating independent landing authority.

Merge bar

Every source mutation invalidates predecessor workflow evidence. Merge only after fresh exact-current-head Rust/documentation/security/SAST gates, resolved blocking conversations, and the qualifying independent approval required by the live organization ruleset. No self-approval, predecessor-head evidence transfer, force push or protection bypass.

GAP-003A unique slice: GET /v1/project-histories/{key}/request returns the
accepted LineageWeave create request on AnalysisRunLiveService. Metric-free;
inference_status remains temporal_association_only. Naruon refused. Does not
re-open cancel lineages. ADR 0087.
GAP-003A unique slice: tepp-project-history-request get mints
lineageweave_project_history_stored_request_exchange onto spawned
tepp-loopback TCP. Empty stdin admitted. Naruon refused. Does not re-open
cancel lineages. ADR 0088.
@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: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@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: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

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

🔍 Coverage evidence remains unverified

Repository rules require 100% production line and branch coverage. Exact coverage could not be verified because Cargo is unavailable in this environment.

Devin Review

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

Comment on lines +140 to +141
if idempotency_key.contains('/') || idempotency_key.contains('\0') {
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.

🟡 Slash keys block stored retrieval

lineageweave_project_history_stored_request_exchange rejects slash-containing keys that project creation accepts. Their stored requests become unretrievable.

Prompt for agents
ProjectHistoryRequest validation accepts slash characters in idempotency_key, and the existing GET-by-id contract percent-encodes and round-trips them. The new stored-request builder, CLI validation, and stored-request path decoder reject the same keys after creation. Make the stored-request GET use percent-encoding consistently with project_history_retrieval_http so every valid POST idempotency key can retrieve its stored request. Update the HTTP and CLI tests to cover an accepted key containing a slash.
Devin Review

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

Comment on lines +28 to +33
let stdout = render_project_history_stored_request_cli_stdout(&invocation, &response)?;
println!("{stdout}");
if (200..300).contains(&response.status_code) {
Ok(())
} else {
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.

🟡 Failures print request-shaped output

For any non-2xx response, run prints the error envelope to stdout. Pipelines can consume error JSON as a stored request.

Suggested change
let stdout = render_project_history_stored_request_cli_stdout(&invocation, &response)?;
println!("{stdout}");
if (200..300).contains(&response.status_code) {
Ok(())
} else {
Err(ApiError::InvalidWirePayload)
let stdout = render_project_history_stored_request_cli_stdout(&invocation, &response)?;
if (200..300).contains(&response.status_code) {
println!("{stdout}");
Ok(())
} else {
eprintln!("{stdout}");
Err(ApiError::InvalidWirePayload)
Devin Review

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

Comment on lines +355 to +356
let bytes = read_bounded(&mut stream, MAXIMUM_HTTP_RESPONSE_BYTES)?;
parse_http_response(&bytes)

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: Connection-close framing is compatible

execute_project_history_stored_request_cli reads until closure. tepp-loopback closes after one response, and exact content-length validation rejects extra or truncated bytes.

Devin Review

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

Comment on lines +348 to +356
let tenant_workspace_id = header_value(headers, PROJECT_HISTORY_RETRIEVAL_TENANT_HEADER)?;
crate::project_history::validate_project_history_registry_identity(tenant_workspace_id)?;
let idempotency_key = project_history_stored_request_path_id(path)?;
let replay_key =
consumer_tenant_idempotency_key(consumer, tenant_workspace_id, &idempotency_key);
let (stored_request, projection) = self
.accepted_project_histories
.get(&replay_key)
.ok_or(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: Stored lookup preserves tenant scope

The registry key combines consumer, required tenant, and decoded caller key. Identical keys in different tenants remain isolated.

Devin Review

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

Preserve #420 query CLI source, fail-closed transport/refusal behavior, contract tests, changelog fragment, and doctoring in the consolidated Analysis Run project-history adapter vehicle. Keep stored-request GET/CLI behavior intact. No new bounded context or architecture authority is created.

@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 f02436236a73824c87c6043fc5d1e0b08cb0d448 (not the stale ade6e27d SHA; not APPROVE; author COMMENT is not an independent approval under ruleset 18156473). Predecessor Checks/reviews do not transfer. Do not un-draft. Do not reopen closed #420 (folded here). Do not ship project-history by-idempotency lookup (duplicates GET-by-id; #429 CLOSED).

Fail-closed read at this SHA:

  • LineageWeave-facing stored-request GET GET /v1/project-histories/{idempotency_key}/request requires tenant_workspace_id through validate_project_history_registry_identity before compose (project_history_stored_request_http.rs). Naruon is refused. NaruonLiveService stays POST-only.
  • Query-CLI stdout remains metric-free with inference_status=temporal_association_only; scientific-acceptance, public binds, hostile origins, and naruon use fail closed per the PR body.
  • Fold of #420 query CLI is one Analysis Run adapter vehicle, not a new bounded context. ADR 0087/0088 are implementation lineage, not separate architecture authority.

Keep tenant-scoped stored-request; do not add an unscoped stored-request-by-client-key disclosure. Unique tepp-project-history-request remains occupied here. 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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant