Skip to content

docs(client): implementation plan for the client launch sequence (#409) - #579

Open
halcwb wants to merge 7 commits into
informedica:masterfrom
halcwb:docs/409-client-launch-sequence
Open

docs(client): implementation plan for the client launch sequence (#409)#579
halcwb wants to merge 7 commits into
informedica:masterfrom
halcwb:docs/409-client-launch-sequence

Conversation

@halcwb

@halcwb halcwb commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Description

Implementation plan for the client side of the launch sequence (UC-1) from the MainEHR integration design V8, with all server-side actions stubbed behind the final API contract.

Key points:

  • Launch token erased from url and history at first presentation (Rule 39); session credential as an HttpOnly, SameSite=Strict cookie, never in a url or response body (Rule 12).
  • Pure client session state machine (Anonymous | Launching | Resuming | Open | Refused | Unreachable) with a stale-request guard and retries; patient changes routed through UpdatePatient.
  • IdentityProvider hop modelled as a RedirectTo launch outcome; the stub never returns it.
  • Server stub fails closed under GENPRES_PROD=1, so the work can ship in alphas without holding the ShipIt release PR.
  • Five PRs, each under 200 lines. The plan is to be picked up in Client/Server: Initial session interactions #574 to correct that scaffold, whose redeem-token hop has no counterpart in V8.

Reviewer note: the D1 decision (url parameters versus sealed launch token) in docs/roadmap/mvpap2019-gap-overview.md is still open. The plan is D1-neutral on the client, because the launch is opaque there.

Author checklist

Reviewer checklist

  • The chosen approach is a good choice.
  • The sequence of steps is complete and sensible.
  • I have documented resources that may help with implementation.

🤖 Generated with Claude Code

Implementation plan for the client side of UC-1 (launch) from the
MainEHR integration design V8: launch erased from url and history
(Rule 39), session credential as an HttpOnly cookie (Rule 12), pure
client session state machine, server actions stubbed behind the final
contract, IdP redirect modelled as a launch outcome. To be picked up in
PR informedica#574 to correct that scaffold. Also records how ShipIt gates
releases, so the plan relies on a fail-closed stub instead.

Refs informedica#409

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This documentation PR defines a staged implementation plan for the GenPRES client launch sequence, including URL credential hygiene, cookie-backed sessions, an explicit client state machine, IdentityProvider return handling, patient-state cleanup, and a fail-closed server stub.

The latest revision:

  • Adds an explicit Retry transition that preserves the Launch and PresentationKey.
  • Limits the same-Launch no-op guard to requests already in flight.
  • Clarifies that refused launches are not marked spent and may be re-verified.
  • Fully addresses the outstanding retry-from-Unreachable finding.

Confidence Score: 5/5

The documentation plan appears safe to merge; the latest changes fully resolve the previously blocked retry path without introducing a new actionable issue.

The explicit Retry message now transitions Unreachable and retryable Refused states back to Launching, issues a new server call, and preserves the original Launch and presentation key. Refusals do not create the spent-mark used to cache successful outcomes, so NoBrowserIdentity retries can re-verify rather than becoming permanently refused. All earlier findings are either fully fixed or resolved with explanatory replies.

Important Files Changed

Filename Overview
docs/implementation-plans/409-client-launch-sequence.md Defines the complete client launch implementation plan and now provides a reachable, identity-preserving retry transition for failed launch presentations.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Launch URL received] --> B[Erase token from URL and history]
    B --> C[Present Launch with PresentationKey]
    C --> D{Outcome}
    D -->|Opened| E[Open cookie-backed session]
    E --> F[Update patient context]
    D -->|RedirectTo| G[IdentityProvider round trip]
    G --> H[Server callback opens session]
    H --> I[Resume from session route]
    D -->|Retryable refusal| J[Refused with Launch and key]
    C -->|Transport failures exhausted| K[Unreachable with Launch and key]
    J -->|Retry| C
    K -->|Retry| C
    D -->|NoRole| L[Offer anonymous open]
    L --> M[Clear patient and derived context]
    E -->|Close| M
Loading

Reviews (5): Last reviewed commit: "docs(client): add an explicit retry tran..." | Re-trigger Greptile

Comment thread docs/implementation-plans/409-client-launch-sequence.md Outdated
Comment thread docs/implementation-plans/409-client-launch-sequence.md Outdated
Comment thread docs/implementation-plans/409-client-launch-sequence.md
Make launch presentation idempotent per browser within the Launch
lifetime (Rule 2), so a transport retry cannot turn an opened session
into LaunchSpent. Specify the IdentityProvider return: the server
callback opens the Session and sets the cookie before redirecting to
/#/session, or to /#/session?refused={reason}, which the client erases
and maps to RefusedAtCallback. Clear the patient through UpdatePatient
None on Closed and OpenAnonymous.

Refs informedica#409

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread docs/implementation-plans/409-client-launch-sequence.md Outdated
A missing cookie cannot tell a lost response from another browser, so
the stub would have handed a second browser the first one's session.
The client now mints a PresentationKey once per page load, keeps it in
memory only and sends it with the Launch; a repeat with the same key
within the lifetime is answered as the first was, any other key or no
key is LaunchSpent (Rule 2, same shape as the Rule 45 submission key).

Refs informedica#409

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread docs/implementation-plans/409-client-launch-sequence.md Outdated
Outcome carries the PresentationKey, and the stale-request guard accepts
a response only when launch and key match the in-flight presentation.
A Present for the same launch while one is in flight is a no-op, so the
key the server recognises is never replaced.

Refs informedica#409

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Comment thread docs/implementation-plans/409-client-launch-sequence.md Outdated
Retry from Unreachable or a retryable refusal re-presents the stored
launch and key; the Present no-op is limited to Launching. The
spent-mark is written only when a session opens (Rules 2 and 40), so a
retry after a transient refusal re-verifies instead of replaying it.

Refs informedica#409

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
halcwb and others added 2 commits September 8, 2026 08:05
Whether the production server exposes the stubbed session endpoints is
a scope question, now tracked in informedica#580 (scope switch). Drop the
GENPRES_PROD fail-closed rule and the release-gating section from the
launch-sequence plan.

Refs informedica#409, informedica#580

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The changelog and commit conventions are repository-wide and documented
in DEVELOPMENT.md; they do not belong in a feature plan.

Refs informedica#409

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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