Repository navigation
feat(identity): add verified invitations with automatic email - #41
Conversation
Retain two fresh second-round approvals and actual rediscovery of both complete assignments. Keep the unchanged plan and population explicit; final-source hosted A/B remains the qualification gate. ADR: 0063, 0076, 0077
Give admission, routing, generation binding, framework capabilities and provenance their own whole-method proofs in the existing collection. Preserve the complete control bodies and one shared capability inventory; leave detectors, production code and execution limits unchanged. Record exact source-token reconstruction and instrumented control/result multiset equality. Clean timing, plan review and full hosted A/B remain required; diagnostic instrumentation is restored and never ships. ADR: 0047, 0063, 0076, 0077
Retain all prior timing rows and add only actual complete passing new Facts, with clean source/tree/binary and raw TRX provenance. Review the new population and both complete assignment discoveries without changing counts, algorithms, concurrency, ceilings or cleanup reserve. Record the first independent review and measured-plan approval; second review and final-source hosted A/B remain open. ADR: 0047, 0063, 0076, 0077
Retain two fresh independent second-round approvals and the complete source/control/timing/discovery evidence. Keep final-source hosted A/B as the remaining qualification gate with unchanged execution limits. ADR: 0047, 0063, 0076, 0077
Expand each nonsealed helper once per detector evaluation while retaining all direct helper visits and existing clean, dirty and restored controls. The three focused controls pass before and after; local mutation duration falls from 122.297 to 6.486 seconds without changing the CI window. Preserve the latest failed hosted attempt and keep complete final-source A/B qualification open. ADR: 0046, 0063, 0069
Record independent semantic and evidence review plus both actual selector layouts without treating local speed measurements as hosted fit. ADR: 0063, 0069
Record the second fresh semantic and evidence reviews while retaining the existing complete hosted A/B qualification gate and CI limits. ADR: 0063, 0069
Include historical stock proofs in the existing closed failure projection. Observe provider SDK milestones and capture startup cancellation before cleanup without exporting raw errors or changing lifecycle authority. Preserve the failed full attempt, existing startup limits and incomplete qualification status. Native controls and a real HTTPS provider smoke pass. ADR: 0062, 0063, 0069
Record independent semantic and protocol review with repeated native controls and raw failed-attempt audit. Keep the provider cause unknown. ADR: 0062, 0063, 0069
Close the second independent review while retaining the unknown provider cause, unchanged bounds and mandatory complete hosted A/B qualification. ADR: 0062, 0063, 0069
Poll incomplete readiness within the existing startup allowance instead of admitting a numeric prefix or refusing an empty publication immediately. Preserve owner, cancellation, native-exit and closed-diagnostic boundaries. Add actual-file and counterfactual controls, preserve the failed hosted attempt, and keep complete clean-source qualification open. ADR: 0055, 0056, 0063, 0069
Retain independent source review and a complete clean-workspace frontend replay while keeping actual demo and hosted qualification separate. ADR: 0055, 0056, 0063, 0069
Keep real renewal and expired-window proof, then hold the next actual pacing callback while the positive Outcome completes. Preserve every assertion, allowed conservative refusal and existing lease/stage bound. Join real callbacks and factories on all exits; retain clean, refusal and isolated dirty-cleanup evidence without claiming hosted qualification. ADR: 0047, 0059, 0063, 0069
Retain independent source and raw-proof review while distinguishing the selected positive schedule from unknown historical CI interleavings. ADR: 0047, 0059, 0063, 0069
Record both fresh review closures and the clean managed browser proof before restarting complete hosted qualification on one stable source. Local evidence does not promote the packet or replace the full A/B pair. ADR: 0063, 0069, 0076, 0077
The final permission promotion leaves no Adopted standards. Preserve the existing status/index check while allowing its truthful zero count. An isolated future-document twin fails before and passes after this fix. ADR: 0069, 0076, 0077
Retain independent raw before/after and cancelled-attempt checks before the next review round and complete hosted source qualification. ADR: 0063, 0069, 0076, 0077
Close the second independent census review and preserve the source-bound qualification gate before promoting final permission and test carriers. ADR: 0063, 0069, 0076, 0077
Promote live permission and catalogue status only after complete same-source hosted A/B and independent original-evidence audits. Keep later entry, UI, Platform and closure work in their owning Phase 03 packets. ADR: 0063, 0069, 0076, 0077 Module: Identity, Tenancy, Customization, Education, Audit
Close the fresh documentation review after qualified A/B and preserve source provenance, later packet ownership and the pending PR review. ADR: 0063, 0069, 0076, 0077
Share the explicit pair rule across seed and API runtime projections so invalid local configuration cannot reach stack startup or migrations. Reconcile verified stale authorization carriers with the delivered code. ADR: 0069, 0076, 0077
Retain the first independent review and complete guarded frontend result for the two verified review fixes before the second review round. ADR: 0069, 0076, 0077
Keep the real launcher fixture's dependency closure intact after sharing auxiliary configuration validation. Record live PostgreSQL/API results and the second independent correction review before updating PR 39. ADR: 0069, 0076, 0077
Replace a racy any-lock observation and timed release with positive SQL acquisition and explicit cleanup ownership. Keep runtime cancellation bounds intact and retain safe source locations for future CI failures. ADR: 0063, 0069, 0076
Retain the independent lifetime and evidence checks together with a real wrong-mode counterfactual before the second correction review round. ADR: 0063, 0069, 0076
Record independent lifetime and diagnostic proof without attributing a historical interleaving or new-head CI success that has not been observed. ADR: 0063, 0069, 0076
Record the maintainer's PR 39 merge and retain exact-source qualification separately from final protected checks. Mark P03-2 complete, refresh the capability overview and point to P03-3 without starting its decision pass. ADR: 0069, 0076, 0077
Compare scope ownership against the pinned provider before selecting a new native trust source. Define creation and replay bounds, explicit permission adoption and a reviewable ten-step packet before runtime work. ADR: 0069, 0078, 0079
Make the native surface and source ownership explicit before approval. Preserve shared provider scope facts, define current action previews and cover warm Tenancy edits alongside identity and protected replay outcomes. ADR: 0069, 0078, 0079
Exercise retained provider capacity, real process loss, late receipt reconciliation and native receiptless finalization through actual Identity owners. Confine irrecoverable cleanup to joined test processes and keep source-bound evidence distinct from final hosted qualification. ADR: 0093, 0047, 0058, 0061
Name the actual enforcement owners and preserve local receipt boundaries without claiming unexecuted hosted or human qualification. Keep the final PR candidate stable while its source-bound CI evidence is collected. ADR: 0093, 0063, 0069
There was a problem hiding this comment.
Sorry @cemililik, this pull request is too large to review
It changes 367 files. Sourcery can review pull requests with up to 300 changed files.
|
Important Review skippedToo many files! This PR contains 425 files, which is 275 over the limit of 150. To get a review, reduce the PR to 150 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to Team to raise the limit. Usage-priced reviews support at most 300 files.
|
Preserve the approved invitation boundaries in legacy test hosts and finite production/schema censuses. Apply the missing parent locks by forward migrations, retain exact provider metadata proofs and align the canonical job policies with the shipped chain. Rebalance advisory CI weights from original completed groups without changing any ceiling. ADR: 0063, 0093 Module: Identity, Tenancy
Record both independent review rounds and the verified evidence bounds. Keep fresh source qualification and actual human observations open for this publication candidate. ADR: 0063, 0093
Read the effective Platform migration chain so schema controls compare the latest installed guard without relaxing body or privilege checks. Preserve only closed phase diagnostics for the two invitation integration facts. ADR: 0093
The session completion path rejects a nonzero exit before recording completion, so the browser-only disposal label cannot describe either invitation fact. Pin its exclusion while retaining the existing browser diagnostic. ADR: 0093
Record the source-bound correction reviews and verified diagnostic finding without granting qualification to the failed attempt or pending human checks. ADR: 0093
Preserve each root and expansion state while avoiding repeated queue entries and path allocation in the authenticated HTTP guard. Keep full mutation coverage, prove late abstract acquisition and retain the failed hosted attempt without claiming qualification from local results. ADR: 0064, 0093
Record both independent review rounds and preserve the failed-source and human-evidence boundaries before publishing the next candidate. ADR: 0069, 0093
Avoid repeated whole-production projections and name scans while preserving exact predicates, occurrence order and fresh mutation scopes. Record the failed hosted attempt and bounded canonical verification without promoting local observations into qualification. ADR: 0062, 0093
Record both independent review rounds and retain the final-source CI and human evidence gates before publishing the next candidate. ADR: 0069, 0093
Record the maintainer's completed P03-4 manual checklist against the unchanged application source. Close the human-check item while keeping same-source hosted A/B and original-archive qualification open. ADR: 0069, 0093
There was a problem hiding this comment.
Sorry @cemililik, this pull request is too large to review
It changes 404 files. Sourcery can review pull requests with up to 300 changed files.
Architecture Inside the changed components — 2 viewsComponent view — Invitation Landing & Acceptance Internal routing and verification path from native HTTP landing through Keycloak UserInfo claim validation to membership grant.
Component view — Encrypted SMTP Custody and Dispatch Isolation boundary where encrypted email envelopes are spooled and dispatched by background workers to external SMTP.
Data flow Data model Review ✨ Nothing flagged · reviewed Tip Run 🪧 More tips
Thanks for using PR Lens! It's free for OSS. If it helped, a star helps other teams find it. |
Keep the existing fixed driver refusal in failure measurements for the exact entry-pagination case without widening diagnostic or result authority. Preserve the original failure and local recheck boundaries. ADR: 0069
Record both independent R1 approvals while retaining the open original cause and final-source hosted qualification boundaries. ADR: 0069
Record four independent approvals without promoting the local diagnostic repair into a cause finding or final-source hosted qualification. ADR: 0069
Hosted runs kept failing in the three facts that start stock Chromium: a live browser that never published its DevTools port, and an invitation fact whose own failure was replaced by a retained-tree disposal error raised under await using. startBffBrowser replaces a browser that stayed live without a usable port file at most once, after stopping it without force, on a fresh profile. The readiness window, flags and cleanup limits are unchanged. BffNativeDriver disposal keeps the first failure it raised and still refuses a cleanup-only failure. Twelve web controls and one driver control pin both. The stall cause stays unproven. ADR: 0069, 0093 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Without dotnet.defaultSolution the C# extension and C# Dev Kit discover every .csproj under the workspace, including ignored local evidence and agent worktrees, and warn that more than 100 projects need a solution. Point them at backend/LearnStack.slnx instead. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Four of the last five hosted runs lose one shard to its whole-job window while every executed case passes, and the cut-off is a different shard each time. Passing shards already sit within a minute of it. ADR-0094 gives verified Architecture and ordinary Docker producers a 45-minute ceiling. Base/native, aggregates, meta, the reserve, operation limits, counts and the plan stay as decided. Dated amendments land in ADR-0063 and ADR-0082; the testing, infrastructure and catalogue standards are reconciled. The delivery log records the run evidence, the weight replay that leaves the plan unchanged, and the open A/B gate. ADR: 0063, 0069, 0082, 0094 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Set the Architecture and ordinary whole-job ceilings to 2,700 seconds through the single validated mode policy and the two producer workflow timeouts. Move every offline pin with them, adding 2,699, 2,700 and 2,701 second boundaries and the former 25/30 minute values as drift. The Ruby workflow reader in the shard-result owner kept a fixed five-second timeout and refused ordinary 6 before any case ran. It now allows thirty seconds; its refusal and safe-load checks are unchanged. ADR: 0063, 0082, 0094 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A stored tenant or branch name may hold control characters because Tenancy only requires non-blank text, yet the SDK refused the recipient inspection and the email stager threw, so every create and reissue for that tenant returned 500. Both now show one clean, escaped line. A refused invitation form is shown again as an editable form: the value kept, the field named, the error tied to it and the chosen role carried hidden. The BFF uses the SDK's own mailbox grammar, so nothing it accepts is refused after sending. The recipient operations require the native source at runtime; the OpenAPI document now states both credentials. The invitation list reads a page's delivery status in one statement instead of one per row, with the detail read's predicate and classifier. The landing form gets the common CSRF-proof guard, and its hidden error describes the field only once it is shown. ADR: 0093 Module: Identity Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The web workflow-ceiling control still expected 25 and 30 minutes for the two producers after the windows moved; the full web run that preceded the workflow edit was not repeated. It now expects 45 for both. The host-rejection counter test listened to a process-wide counter by name, so any concurrent host refusal could move it. Its listener is bound to the fixture host's own meter scope, and a control that increments the same name from an unscoped meter fails without that scope. The 30-second workflow-reader allowance gets its own control: the bound, the unavailable-parser refusal for a timeout or a missing reader, and the document refusal for a reader that fails. ADR: 0094 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ADR-0094 names ADR-0062 and ADR-0075 as changed but neither carried a dated amendment, and it had no Amendments section of its own; all three are added. The decision index lists all four disclosures. The delivery log records the review round: what the hosted run at 602c57a showed, what three reviews found at HEAD, what was corrected, what was not accepted and why, and what stays the maintainer's call. It also corrects the browser-start record, which cited a standards section that states no infrastructure-retry rule. providers.md now says the message body also prints the code, as ADR-0093 intends; the database standard describes the page-wide status read; the tenancy permissions document loses a stray blank line at its end. ADR: 0062, 0069, 0075, 0093, 0094 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The hosted run at 8276408 failed twenty-two jobs at the Release build gate on CA1305 and CA1863 (string.Format building the SQL scope) and CA1068 (a CancellationToken that was not the last parameter), all in the new page-wide status read. Warnings are errors only when CI is true, so the local builds showed them as warnings and the output filter kept only the error count. The scope predicate is one compile-time constant appended to each statement and the token is the last parameter. The whole solution builds with CI=true and --no-incremental with no warning, and the architecture guard, classification controls and both real-database invitation flows pass again. ADR: 0093, 0069 Module: Identity Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Hosted run 42238072858 failed ordinary 0 with browser-devtools plus a failed cleanup. The previous replacement required an unforced stop of the stalled Chromium, but a start-up that does not answer SIGTERM is killed by the owner's SIGKILL after two seconds and reported as forced, so no replacement ran and the final disposal counted the same stop as failed cleanup. Real owned processes reproduce that pair with the old code and a clean replacement with the new. The fixture owner gains retireChild, which releases a child once its whole group is confirmed absent; dispose still refuses forced stops of any other child. startBffBrowser retires through it, allows two replacements instead of one, and each DevTools wait is 20 seconds instead of ten. The native driver gives the entry and invitation browser phases the 150 seconds the browser result already had. The stall cause stays unproven; the retry is bounded insurance, not a cure. The real invitation fact passes locally in 45 seconds, and in 66 when its first browser is a start-up that ignores SIGTERM. The full web suite passes 3,767 cases, and the CI-mode solution build has no warning. ADR: 0093, 0069 Module: Identity Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Summary
Approach
Acceptance rechecks tenant/branch lifecycle, current inviter delegation and the verified recipient. Invitation, Membership and both central MUST audit events share one transaction; session admission remains separate. Encrypted SMTP custody, identifier-only jobs and immutable attempt receipts preserve conservative Unknown recovery. SMTP acceptance means submission acceptance, never inbox delivery.
The native English/Turkish flow captures a fragment-only code, supports no-JavaScript forms, and preserves existing session/CSRF/lifetime limits. No new general directory, permission pair or provider-admin credential is introduced.
Tests
The implementation baseline passed 3,589 Unit tests, ten Contract tests, guarded frontend (3,932 cases across 130 files/two packages), type checking and lint. Actual scoped PostgreSQL, provider, SMTP, native-browser and authority/schema checks are recorded in the delivery log. These historical scoped results are not final-source hosted qualification.
The latest test-only recurrence-index repair passes 57 distinct affected cases with zero skips, including all 48 recurrence cases, index lifetime/identity controls and five shared callers. All 153 source-input hashes match the tested candidate. Its focused case improves from 3.090 to 2.156 seconds in one local comparison; build-inclusive wall timing does not improve, and no hosted-fit guarantee follows. Two fresh independent review rounds approve the correction. Test coverage, timers, workers, VM/resource limits, weights and selectors are unchanged. The separate unchanged complete browser/session recheck passes once; its earlier positive DevTools startup failure remains unattributed.
Current PR candidate: head
29381545afe4725f4df365aef2e16a2d4bb66d15, baseef344c0f77572e5b6e8009f9f8608cddd48ce41a; GitHub's current PR merge ref isbc143da7b28b381382f99b791d0b0ffda71c2747. Since the previous description (head82573d60) nine commits land. A stalled stock-Chromium launch is replaced in the two native browser fixtures and driver disposal keeps the first failure it raised (8f8da7b1); the replacement first refused to run after the stalled browser needed SIGKILL, and now retires it however it stops, allows two replacements and waits 20 seconds per start (29381545). The new status read's analyzer violations that failed the warnings-as-errors build are corrected (93fd1f59). ADR-0094 moves the Architecture and ordinary whole-job ceilings to 45 minutes and the workflow-reader timeout to 30 seconds (37e5cb35,602c57af). A review round corrects verified defects (af781407,cf23e52d,8276408f): names holding control characters, editable invitation validation, native-source security in the OpenAPI document, one delivery-status statement per page, the landing form's CSRF guard and described-by, a stale web ceiling pin and a process-wide host-rejection meter. The delivery log's review corrections lists what was accepted, what was not and what remains the maintainer's call.Hosted history since the previous description:
82573d60has two ordinary producers fail (Chromium readiness, retained tree).ae62cc10has one producer reach its window with 294 of 295 cases Passed, and one refuse before any case on a five-second parser timeout.602c57afpasses all eighteen Architecture and ordinary producers, with one stale web ceiling pin and one process-wide meter case red, both corrected incf23e52d.8276408ffails twenty-two jobs at the warnings-as-errors build on three analyzer violations.93fd1f59has 23 of 27 jobs succeed: one ordinary producer fails on a Chromium start stall whose replacement was refused after SIGKILL, and one Architecture producer finishes its cases but hangs at its evidence upload until the job ceiling, which is recorded as a hosted-runner loss. The workflow for this candidate is run 42252617289; no successful hosted qualification is established for it.Locally this candidate passes 3,611 Unit, ten Contract, 192 SDK and 3,767 web cases (120 files), 102 selected Architecture cases and the real-PostgreSQL native invitation cases and browser fixtures it touches, including the invitation-registration fact with its first browser replaced by a start-up that ignores SIGTERM. The full Architecture and Docker integration suites were not run locally. The maintainer's manual accessibility acceptance below covers the application at
0fcc486a, not the later label, form-error and landing changes. These later corrections have not had the two fresh independent review rounds of the earlier steps.0fcc486ab7285f9d828e48b25511d81f860d3727: the maintainer reports completing and accepting every supplied checklist item, including keyboard/focus/forms/errors, VoiceOver, zoom/reflow/contrast, English/Turkish invitation journeys and no-JavaScript recovery. This is maintainer-reported evidence; exact tool versions and raw measurements were not supplied.29381545, completes all 27 jobs successfully, and its merge source has the same tree as the squash merge. Earlier history, superseded by the runs above: the last completed preceding-candidate whole-workflow A, attempt 3, at head4e4202db/ merge source05601e29, finishes with 25 successful/two failed jobs. One native entry-pagination browser case in ordinary-7 reports Failed; the producer receipt reportsowned_completion_missingwith workload errortests_failed. Integration aggregation then refusesproducer_not_successful. This is distinct from attempt 2's partial-rerun timestamp refusal. All 24 available original artifact ZIPs and original logs are retained with API size/SHA-256/CRC checks. The exact unchanged entry-pagination case passes one fresh isolated local recheck (39.681 seconds; actual runner/test exits 0 and normal cleanup, unchanged source); the hosted cause remains unconfirmed. No successful-current-source qualification is claimed.Evidence retention, corrected 2026-11-06: the statements below that original ZIPs and logs are "retained" refer to maintainer-local copies. The ignored local
artifacts/directory (18 GB) was deleted on 2026-11-06 at the maintainer's direction, so those statements cannot be re-verified from this checkout, and whether a given original ZIP survives elsewhere is not established here. GitHub keeps only the latest attempt's artifacts for a run (for exampleci-proof-41985858191-1-*is no longer listed; attempt 2's is). The recorded hashes, sizes and counts are the remaining record.Preceding head
4e4202dbattempt 1 has 25 successful/two failed jobs: ordinary-0 reaches its fixed deadline with 293 Passed of 297 selected A cases, leaving four censored, and integration aggregation refuses. Attempt 2 is a partial rerun: only ordinary-0 and integration aggregation actually rerun; the 249/249 Passed ordinary-0 cases use layout B, not A's 297-case population. GitHub projects older successful jobs with later creation times and old start/end times; the aggregate refusesapi_timestamp_invalid. Only one current-attempt producer archive exists. Its missingaggregate.jsonupload is a consequence of that refusal. All 24 attempt-1 and one attempt-2 original ZIPs/logs are retained with API size/SHA-256/CRC checks. These partial results are not complete qualification; the subsequent complete attempt 3 and its retained failure are recorded above.Retained evidence for preceding head
0fcc486a(actual merge sourceb691a68f): A attempt 1 passes all 27 jobs and 8,290 backend cases; frontend reports 3,932 passed across 130 files/two packages. All 25 original ZIPs/logs are retained and independently reconciled across backend/native/frontend/public/OpenAPI/SARIF surfaces. Ten credential-control log display names have narrow GitHub display-only masking; IDs/outcomes/durations and archive names remain verified. Whole B attempt 2 has 25 successful/two failed jobs: one ordinary producer reaches its fixed deadline after 250 Passed of 263 selected cases, leaving 13 censored; its integration aggregate refuses. All 24 available original ZIPs/logs are retained. All 13 censored identities pass one unchanged fresh local recheck, which neither completes B nor establishes a unique cause. Two private timing-data studies are complete and unapplied. This preceding-source evidence is retained history, not current-candidate qualification.Four earlier full automatic A attempts remain failed: first, second, third, fourth. All available original ZIPs (23/24/23/23) and original attempt-log archives were retained and checked before corrections. The fourth had 23 successful/four failed jobs and 8,280 Passed/one Failed/nine censored producer cases. No failed, censored or earlier-source fragments combine into qualification.
Risk
Tenant/organization isolation and pre-membership authority change only as bounded by ADR-0093. Dedicated database functions, ordered fences and real PostgreSQL/provider controls cover that boundary. Missing decryption keys, ambiguous submission or incomplete cleanup refuse or retain ownership; reissue cannot promise an older message will not arrive. Existing v2 Tenant
tenancy.setting.writeholders gain the exact invitation-lifetime setting; v1 has the default and no new grant. The review round leaves maintainer decisions open and unchanged here: the reach oftenancy.setting.writeto built-in roles, a send budget for create and reissue, KeycloakverifyEmailand changed-email proof, SQL-level reach of the admission token, envelope retention and the process-wide SMTP fence after a failed cleanup. They are listed in the delivery log.Ready for review at the maintainer's request on 2026-11-06: implementation, per-step reviews and maintainer manual checks are complete. Full same-source CI A/B and original-archive qualification remain open. P03-3's separate evidence/manual follow-ups retain their own status. No merge is requested.
Migration / Rollback
Apply the committed Identity and common Infrastructure migration chains through the existing migrator. They add Invitations, workflow-failure state, encrypted SMTP custody and the exact protected-receipt targets. Two additive forward migrations apply the missing parent lookup locks to existing installations while retaining prior guard bodies, models, relations and grants. Provider custody and retained receipts require a reviewed forward migration; do not drop uncertain attempts or rotate away required keys to roll back.
Configure the operator SMTP/TLS/encryption key ring and database diagnostic privacy before enabling invitation writes, following the Identity provider runbook. Keycloak's account-verification sender is separate. Local Mailpit is not production SMTP/TLS or inbox-delivery proof.
Related
Prepared with Codex.