Skip to content

feat(api): record active-session responses over HTTP - #195

Closed
cursor[bot] wants to merge 7 commits into
mainfrom
cursor/bc-7c52ddb8-b212-4e20-8952-48ee9b2996ad-cc98
Closed

cursor[bot] wants to merge 7 commits into
mainfrom
cursor/bc-7c52ddb8-b212-4e20-8952-48ee9b2996ad-cc98

Conversation

@cursor

@cursor cursor Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Why

A purchaser who already has an Active session still cannot submit an answer over HTTP. TRD §18 lists POST /v1/sessions/{session_ref}/responses as the next public family after session create. Domain response recording exists on protected main; this slice makes that write discoverable without creating sessions, listing instruments, or persisting ledgers.

Do not mix this onto #149 session HTTP, #165 instrument catalog HTTP, or response persist/reload (#151/#174/#182).

What

  • In-process POST /v1/sessions/{session_ref}/responses records one answer on an injected Active session when item_version_ref belongs to that session's published release.
  • Exact Idempotency-Key replay returns the original event without minting a second identity.
  • Created, paused, unknown, numeric/encoded session identities, foreign items, missing keys, non-canonical digests, unknown JSON, and conflicting replays fail closed with RFC 9457 problem details that do not echo payload bytes.
  • As-built OpenAPI 3.2.0 is limited to that one operation (openapi/responses.yaml).
  • README and doctoring tell the purchaser the next action: Complete the session after every item is recorded.

Boundary

This does not create or activate sessions, list instruments, persist response ledgers, deliver item text, or implement commands/results. #149 remains the session HTTP landing vehicle. #165 remains the catalog HTTP landing vehicle.

Verification

  • cargo test --test response_http_contract
  • cargo test --test documentation_architecture_contract
  • cargo clippy --all-targets -- -D warnings
  • Runtime CI / rustdoc / security workflows on the unchanged exact PR head
  • independent non-author approval under the live repository ruleset

Residual accepted on this slice

Open in Web View Automation 

Expose POST /v1/sessions/{session_ref}/responses so a purchaser can
submit one answer on an Active Korean Big Five session. Hide Created,
paused, unknown, and foreign-item writes. Keep the OpenAPI 3.2 contract
limited to that one operation.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
@cursor
cursor Bot requested a review from seonghobae August 16, 2026 16:24
Keep the response family off protected main until an unchanged reviewed
head is integrated, and keep it separate from #149, #165, and persist
reload slices.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>

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

Stale comment

Review (exact head 6ca9d4e)

This is the in-process POST /v1/sessions/{session_ref}/responses landing. It records on an injected Active session and does not persist across restart. That honesty is correct.

Keep persist/reload on #182 (7a72ee1). Do not fold response_event PostgreSQL onto this HTTP slice, and do not land this beside #149 session HTTP or #165 catalog HTTP.

A Korean IPIP Quick buyer still loses answers on process restart until #182 lands. After #182, compose persist under this handler in a later successor — not by expanding this head with a second store.

Independent last-push approval is still required. This review is not an approval.

View PR

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

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

Stale comment

Exact head 6ca9d4e is the right landing vehicle for in-process POST /v1/sessions/{session_ref}/responses. Do not fold session create, catalog list, persist/reload, item text, or Complete onto this PR. Do not open a second response-event HTTP PR.

The write path is sound: Active-only new answers, release membership, exact Idempotency-Key replay (200, no second server_event_ref), conflicting reuse 409 without echoing payload bytes, and OpenAPI limited to this one operation.

This automation cannot REQUEST_CHANGES on its own PR. These findings still block treating the head as review-clean:

  1. SessionNotActive always tells the purchaser to Activate. That is the wrong next action for Paused (Resume via POST /v1/sessions/{session_ref}/commands) and for Completed/Expired/Cancelled (do not reopen). The paused fixture only asserts the URN.
  2. apply_request_read completes on the first header terminator before Content-Length is satisfied. A split-packet body on 0.0.0.0:$PORT becomes a false 400. The listener test writes headers+body in one write_all.
  3. Missing realistic paths: Completed/Expired/Cancelled write, second-item sequence: 2, and exact-key replay after Pause/Complete (domain replay is checked before accepts_responses()). Do not add an HTTP-level Active gate before ledger.record.
  4. As-built OpenAPI never states the ADR-0014 residual: this slice is anonymous/unauthenticated in-process transport with session_ref resource scope, not a hosted authorized API.

Also stop header_value from scanning past the first blank line so a body line cannot supply Idempotency-Key.

Independent non-author approval and exact-head checks remain required. This review does not approve.

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

Comment thread src/response_http.rs
Comment thread src/response_http.rs
Comment thread src/response_http.rs
Comment thread tests/response_http_contract.rs
Comment thread openapi/responses.yaml

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

Review

Keep #195 as the in-process HTTP write family. Do not fold it onto persist landing PR #208.

#195 correctly records one Active-session answer, exact Idempotency-Key replay, and RFC 9457 fail-closed paths without echoing payload bytes. Restart durability is #208, not this transport.

Composition note: #208 adds WriteError::InvalidStoredSequence. After that persist head lands, write_problem on this family must handle the new variant or the HTTP crate will not compile. Do not add persist/load to this branch to paper over that. Handle the new error as a 409 that tells the operator to restore a contiguous 1..n ledger, then keep HTTP and persist as separate PRs.

Do not mix onto #149 session HTTP or #165 catalog HTTP. Independent last-push review is still required. Do not self-approve.

View PR

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

…oncile-20260820

# Conflicts:
#	CHANGELOG.md
#	docs/TRACEABILITY.md
#	docs/adr/0014-api-and-event-contract-representation.md
#	docs/doctoring/standards-and-evidence.md
#	tests/documentation_architecture_contract.rs
@seonghobae

Copy link
Copy Markdown
Contributor

Exact current-head evidence (2026-08-20, Asia/Seoul): head f1127b604a1834f7f7d393cdac3a8d12dbabaf90 includes response-event HTTP plus a non-force merge of protected main 5544149ca5dc55d2bfc3402cc59c03c44830de5f. Local verification on this exact merged head: response_http_contract 5 passed; documentation architecture 11 passed; active traceability 1 passed; cargo fmt --all -- --check; git diff --check; cargo clippy --all-targets -- -D warnings; full TEST_DATABASE_URL=postgresql://seonghobae@localhost/postgres cargo test -q --all-targets passed. The response route remains in-process and persistence/live integrations are explicitly outside this slice. This is evidence only; PR is not claimed merged.

@seonghobae

Copy link
Copy Markdown
Contributor

@OpenCode review Please independently review exact current head f1127b604a1834f7f7d393cdac3a8d12dbabaf90 for the response-event HTTP boundary, RFC 9457 errors, idempotency/replay behavior, documentation mapping, and protected-main merge. Report findings against this SHA; do not review an older head.

seonghobae and others added 3 commits August 26, 2026 10:50
# Conflicts:
#	CHANGELOG.md
#	docs/TRACEABILITY.md
…e contract

Cover the response HTTP transport family's fail-closed arms end-to-end:
malformed request lines and versions, missing/unusable body framing,
uncataloged release bindings, invalid-reference idempotency keys,
server-reference conflicts, snapshot-requires-completed mapping,
JSON escape/control decoding, duplicate keys, multi-chunk reads,
Allow:POST advertisement, read-loop collapse, and the internal-whitespace
idempotency-key rejection arm.
The line-coverage contract failed on five phantom lines even though every
line executes somewhere: llvm-cov sums per-instantiation-group aggregates
with independent max()es, so write_problem and read_http_request needed a
single binary instance covering their complete bodies. The lib unit tests
now sweep every WriteError arm to its RFC 9457 problem mapping and run the
read loop happy path over a real loopback connection, which also closes
the two branch-contract gaps.
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.

2 participants