Repository navigation
feat(#1169): give award recipients a person record from their first award - #1209
Conversation
…ward Recording an award for a new recipient now creates their person record in the same transaction: a member and particulars whose source is the award. They stay off the register of members and Shareholders until shares are issued. Later awards, allotments, grants and transfers name that member with the retained particulars, so none of them can send different particulars under an award recipient's ID; a new-member request under it is refused. - Model: particulars gain `source_award`, one of the one-source options. - Database guards (shared/0014): the particulars guard accepts an award source only from the company's award to a new recipient; a member insert during an award needs that award; a deferred check refuses an award that commits without its person record; member identity holds while the person has an award; copied first holdings compare with current particulars; grant and allotment digests omit an empty award source. Existing award recipients without a member get a person record from their earliest award. - Retention: particulars of a person with an award are kept, and their particulars can be changed, like a current member's. - API: awards add `recipient_name` and `recipient_residential_address` (current particulars); the members list adds `on_register` and shows award-only people to award readers only; `award_recipients` stays empty for the mobile app until #1201. - Particulars requests work for award recipients before any shares. - Docs describe person records; the backend suite adds one case (26). Refs #1169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
The award case records an award with the person record skipped. The deferred check refuses it at commit, so neither the award nor a member is written. Refs #1169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Checks at
The changed test case now expects 503: the deferred check refuses at commit, and the API reports that as its generic database error. No award or member is left behind. |
The members list hid every member with no register position unless the reader could see their award. That also hid members created by a wallet link before their first shares, which the chain grant's documentary link flow requires. Only award-only people are now hidden from readers who cannot see the company's awards, and on_register is false only for them. Two member-list assertions that still checked the always-empty award_recipients now check the members list itself. The person-record case checks that a member without shares or an award stays listed. The docs give the backend case count and the award refusal wording. Refs #1169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Independent review: BLOCK at d9e643e PR #1209, "feat(#1169): give award recipients a person record from their first award". Reviewed the exact head One blocking finding: the new members-list filter drops more people than award-only recipients. It breaks the Depth of read
Commands and results
Mutations (each reverted; worktree clean after each)
Verified
Findings
|
|
Checks at The fix:
Tests:
Docs:
Checks:
The reviewer's delta review of this head is running. |
The person-record case now also lists members as a register reader who can't read the company's awards (issuer identity required, owner unverified). The award recipient is absent and every listed row reads as on the register. The flag's description says it is false only for an award recipient who has never been on the company's register. Refs #1169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Independent review delta: PASS at 71ff9da PR #1209, delta review of the fix for the earlier BLOCK ( The blocking finding is fixed, with the suggested change. One expectation from the request doesn't hold: removing Depth of read
Commands and results
Mutations (each reverted; worktree clean after each)Each ran against
Verified
FindingsResolved from
|
|
Independent review delta: PASS at 49de9c6 PR #1209, second delta review, at pushed head My M5 mutation (privacy filter removed) now fails the suite, as expected. The merge of main at 9fdfc88 is clean, Depth of read
Commands and results
Mutations (each reverted; worktree clean after each)
Verified
Findings
|
|
The owner approved the journey page on 21 October 2026, relayed from the parent session: "the journey page is ok." The decision is on #1169. This PR can merge once main is merged in, an independent review passes at its merging head, and CI is green on a branch up to date with main. |
…ds see The privacy assertions held on an empty members list too. The case now also requires the class's shareholder in that reader's list. Refs #1169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Checks at the merge candidate
Owner's OK on the journey page, 21 October 2026, given over Remote Control in the parent session and relayed from there (recorded on #1169): "the journey page is ok. Dont start the mobile, post everything in the git hub issues and handover everything to another agent to continue." |
|
Independent review delta: PASS at 5a4f03c PR #1209, final delta review, at merging head The merge of main at 2a05de4 is clean, the branch's own changed lines are unchanged apart from the one-line test The BLOCK I recorded at d9e643e (finding 1 in Depth of read
Commands and results
Mutations (each reverted; worktree clean after each)
Verified
FindingsNo new findings. These carry over, all non-blocking and unchanged:
|
|
Independent review delta: PASS at 969cf2f PR #1209, last delta review, at local merging head The head is 5a4f03c (my PASS) merged with origin/main at 7ba6fed. The merge brings in only main's Depth of read
Commands and results
MutationsNone run for this delta, because there is no code change. The mutation results at 5a4f03c (D1, D2 and D6 all Verified
FindingsNo new findings. The non-blocking notes carry over from
|
Main's class rights added tokens 0012, so the award person-record migration becomes 0013 after it, and the shared guard installer depends on 0013. The backend case count is 27 with both features. Refs #1169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Independent review delta: PASS at 29de1a7 PR #1209, delta review at merging head The merge of main's class rights (b8dd835) is clean, and 29de1a7 only reorders our migration after it. The PR's Depth of read
Commands and results
Interaction with class rights
MutationsNone run for this delta. Findings
|
|
Independent review delta: PASS at 1f25780 PR #1209, delta review at merging head The head is 29de1a7 (my PASS) merged with origin/main at 37c7b4a (#1252). The merge brings in exactly #1252's Depth of read
Commands and results
MutationsNone run for this delta, because none of the PR's code changed. The results at 5a4f03c (D1, D2 and D6 caught) Verified
FindingsNo new findings. The non-blocking notes from
|
|
Merge record: squash-merged as
Note for local databases: a database that applied this PR's earlier migration name, #1216, the web half, follows next. |
Refs #1169
Backend half of #1169: award recipients become person records, the owner's option A from #1165. The web half is #1216, stacked on this PR. Both wait for the owner's OK on the journey page before merging.
What changed
Person records. Recording an award for a new recipient now creates their person record in the same transaction. That is a member, plus particulars whose source is the award.
member_reference_conflict), and different particulars are refused ("must match the retained particulars"). That closes the gap in the issue comments for all four flows.Database guards (
shared/0014_award_person_records, re-installing from the SQL files):register_award_record, by the recording user, dated today.tokens_member_identity: a person's identity holds while they have an award, so member access keeps working. The old award-copy fallback is gone.tokens_mirror_award_identities_valid: copied first holdings are compared with the person's current particulars.source_award_id, and the particulars snapshot adds it only when set, so existing digests and snapshots don't change. The Python transfer snapshot matches.Retention:
_beyond_retention).source_awardwhen they replace the particulars.API (snapshot and generated types updated):
recipient_nameandrecipient_residential_address, the person's current particulars. The award keeps its own copy.on_register. It shows award-only people only to readers of the company's awards, asaward_recipientsdid.award_recipientsstays in the response, always empty, andon_registeris optional in the schema, so the mobile app and its fixtures keep compiling and working until Mobile: the remaining UX standards and register work #1201.source_award.Docs:
business/issuing-shares.md,register.md,member-records.md,engineering/records.mdandbackend.mddescribe person records.Not in this PR:
on_register, award records showing current particulars, a correction path from the person page, and removing the register-setup award-identity branch.Tests kept, removed and consolidated
Backend: one case added (cap 150). Before main's class rights case this was 25 → 26; with it, the merged branch runs 27. The new case is
test_an_award_records_one_person_whose_particulars_every_later_flow_keeps. It checks:Adapted to person records, with no cases removed:
linked_grant_payloaddefaults to an existing member.Client suites: unchanged at dashboard 20/20, shared 10/10 and mobile 10/10. The shared award fixture gains the two new fields.
Checks
scripts/test-backend.pythrough the local wrapper; throwawaypostgres:16-alpine; venv with the CI library pins): audit, lint, system, migration consistency, freshmigrate,check_rls_roles,check_rls_catalogue, and the ordinary suite (27 tests with main's class rights case, OK). Theschemaphases need Python 3.13.15. Instead I exported the schema with the CI library pins against my migrated database: it differed from the snapshot only by the three fields above, and I updated the snapshot and generated types from it. CI's backend job is the record.POSTGRES_DB, migrated from current main, holding an award-only recipient recorded with the old code): the migration gave them a person record from their award. The members list showed them withonRegister: falseand an emptyawardRecipients. An invitation to them was recorded under the new identity rule.tscpass. Client suites pass (20/10/10).make preflight: results on the PR.Mobile
No mobile changes. For #1201: the import screens read
awardRecipients(now empty), and the transfer screen still has anawardOnlynew-member path, which can't trigger now. Both can go once mobile readsonRegister, and the API field can then be removed.🤖 Generated with Claude Code