Repository navigation
Promote QA → production (26 commits) - #1263
Merged
Merged
Conversation
* docs: freshness sweep — 106 entries (upstream@f71de1eb) Updated: - dependency-graph, service-data-access-map, authorization-inventory - about-page-packages, docs-readme-index - 76 editorial docs (Board read-only access, section-owned roles, authenticated-by-default, folded section seams, event scoping) Pruned: docs/superpowers/plans/2026-09-25-workgroup-budget.md Flagged for review (see docs/freshness/last-report.md): - 7 questions Mode: diff Previous anchor: cb3d8b3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5iJNYcyZq3Yfh7pjv * docs: drop derived counts from sweep docs and catalog prompt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5iJNYcyZq3Yfh7pjv --------- Co-authored-by: Claude <noreply@anthropic.com>
The roster is the kitchen assembling a few hundred people's allergies, not someone looking up one person's health data, so a reveal records one scope row (actor, week or day, person-row count). The per-member rows and the member's reveal list on /Cantina/Dietary go. Rule atom updated. Claude-Session: https://claude.ai/code/session_0186neA56jhtewg3fMbWo2Jd Co-authored-by: Claude <noreply@anthropic.com>
* Holded single mirror, phase 1: mirror fields, reads and pages - Ledger lines keep Holded's entry id and its manual Checked tick (nullable columns, generated migration). - The service no longer loads the whole ledger table: balances, sums and counts are grouped in SQL, statements load only their entries. - IHoldedService gains IsConfigured, GetEntryAsync, GetPurchaseLinesAsync, GetOpenAmountsAsync, GetSumsByAccountAsync and GetChartAsync. - /Holded becomes a summary; new /Holded/Accounts (grouped chart with English PGC names) and /Holded/Calls; account and entry pages show the entry id and Checked. The Finance doc-sync row and the IHoldedFinanceService call behind it are gone. - IHoldedClient's remaining external callers recorded as CENTRAL-105. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA66h1oBWsk6677PEqK * Add Holded's own spellings to the PGC names; trim name tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA66h1oBWsk6677PEqK * Drop Holded tests that repeat the service-level read tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA66h1oBWsk6677PEqK * Holded: report an unsynced Checked as null; emit details open only in a conditional Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA66h1oBWsk6677PEqK * Holded: English names for Holded's chart wording; open document amounts count refunds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA66h1oBWsk6677PEqK --------- Co-authored-by: Claude <noreply@anthropic.com>
* Holded single mirror, phase 1: the IHoldedWrite face Ensure-style writes taking Humans keys and returning outcomes, never Holded ids: creditor contact, purchase document, expense account, purchase document delete (refused for foreign notes or payments, then a ledger sync), and the journal entry post. Contacts now read custom_id and type for the lookup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA66h1oBWsk6677PEqK * Holded: whitespace format in HoldedWriteTests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA66h1oBWsk6677PEqK * Holded write face: name match across creditor-range contacts, live expense-account check, notes as the document key Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA66h1oBWsk6677PEqK --------- Co-authored-by: Claude <noreply@anthropic.com>
* Add section-map skill: C4 component map of one section Draft from the trial runs on Teams and Cantina: screens on top, services in the middle, repository at the bottom, neighbours in a slim column, public interfaces on the section boundary, walkthroughs, drift last. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA795R7Sjqt4qB9GkgL * section-map: caching decorator row, controller reads of other sections From the Camps trial run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA795R7Sjqt4qB9GkgL --------- Co-authored-by: Claude <noreply@anthropic.com>
… data (#2225) * List every third-party processor on the Privacy page The page named only Google OAuth and Google Workspace, but member personal data also goes to Gmail relay, Google Maps, Stripe, Holded, Ticket Tailor, MailerLite and Anthropic. A GDPR disclosure must name them all; the list now sits in a delimited block so future integrations know to extend it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BqfQVmKktFiD5NkbMvXo2B * privacy: drop unclear 'pending consents' from Anthropic entry; drop redundant end-of-list comment Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BqfQVmKktFiD5NkbMvXo2B * privacy: registered office is Madrid, not Andalucía; add NIF Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BqfQVmKktFiD5NkbMvXo2B --------- Co-authored-by: Claude <noreply@anthropic.com>
…talog (#2226) * docs(readme): match config, features and milestones to the current app The configuration tables named keys from before most integrations existed and implied dotnet run reads .env; the contributing link pointed at a file that lives under .github/. Milestones collapse to one row per month. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BqfQVmKktFiD5NkbMvXo2B * docs(github): issue-template sections follow src/Sections The Section dropdown still offered Legal, Board and Profile, and pointed at docs/sections/, which no longer holds section docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BqfQVmKktFiD5NkbMvXo2B * docs(processes): list the skills that exist today /sprint, /maintenance, /code-review, /codex, /gemini, /resharper and /nuget-vuln-check are gone; plan-sprint, section-doctor, the debt and freshness skills, fix, check-pr, reuse-review and others were missing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BqfQVmKktFiD5NkbMvXo2B * docs(contributing): fix the README link and name the rules that win The setup link resolved to .github/README.md, and design-rules.md was presented as the top rule source when AGENTS.md and Peter's rules sit above it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BqfQVmKktFiD5NkbMvXo2B * docs(guide): correct Getting Started and Glossary against the code Signup now runs through the /OnboardingWidget name gate rather than /Guest, the setup page explains tiers instead of offering a selector, and the help button no longer offers feedback. Glossary camp-lead, season-status, sound zone, section and Shifts Admin entries were out of date. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BqfQVmKktFiD5NkbMvXo2B * docs(readme): point dev login at the login page panel /dev/login has no index action; the personas are offered on /Account/Login. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BqfQVmKktFiD5NkbMvXo2B --------- Co-authored-by: Claude <noreply@anthropic.com>
…ed one never reads as failed (#2227) * doctor(Consent): open run file * doctor(Consent): target shape covers the member-review lane * doctor(Consent): sync job and its runner are section-private Only Consent's Section.cs names SyncLegalDocumentsJob; its sibling job is already internal. Rule: memory/process/reuse-first-change-discipline.md (public surface needs a reason). * doctor(Consent): every refused signature gets a message, a recorded one never reads as failed A NotFound refusal showed nothing; a failed onboarding report after a recorded consent showed 'submit error'. Review gates on the same name check Submit refuses on, from the loaded user. Rule: memory/code/comments-earn-their-place.md (comments kept to the why). * doctor(Consent): docs and comments say what is true now IConsentWrite's summary said the caller audits; RecordConsentCheckAsync audits itself. Consent.md named the suspension as Consent's job (it is Users'), narrated removed navs three times and carried lane and dated labels. authorization.md now lists the policy Consent registers for Onboarding. Rule: memory/code/comments-earn-their-place.md. * doctor(Consent): run file, debt ledger * doctor(Consent): PR number * doctor(Consent): a failed cache reload after a recorded consent no longer reports the signature as failed The decorator already evicted every alias before reloading; the reload error now logs instead of propagating to the controller's error flash. Codex round 1 on #2227. * Governance: statutes empty-state string in its own resx Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA4NJZtkCuc6yysafYp * Consent: record the purpose Peter approved Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA4NJZtkCuc6yysafYp --------- Co-authored-by: Claude <noreply@anthropic.com>
* Read Workgroups expense accounts from the Holded mirror (CENTRAL-105) * Use the Holded read service for Expenses sync status (CENTRAL-105) * Remove unused purchase document detail fields * Remove unused Holded connector fields * Move ticket sales display ordering into the controller * Move ticket dashboard and holdings ordering to renderers * Keep workgroup document ordering in the views * Move workgroup member ordering into the views * Audit camp image reordering with the acting manager * Audit manual camp historical name changes * Localize container breadcrumb navigation for screen readers * Clean placement images after deleting a container * Use shared invariant date formatters in Razor views * Keep creditor contact matching in the pure duplicate matcher * Reuse the shared timestamp pattern for migration snapshots * Retire the drained invalidator warning exception * Preserve Unicode when truncating HTTP error metadata * Unify camp and team projections in the Store summary * Resolve Store accounting reads through the existing reader * Localize shared table filter controls * Localize shared pager navigation labels * Save grant program fields and manager changes atomically * Save preapproval program fields and managers atomically * Save rota fields and tag selections atomically * Localize shared volunteer search result controls * Save workgroup membership changes with their system log * Save workgroup transitions and their required records atomically * Save workgroup document transitions with their system log * Keep campaign picker and coverage pie ordering in presentation * Order shift department options in their presentation consumers * Keep shift rota and dashboard chart ordering in page builders * Order store summary products in the view * Order board and team detail members in controllers * Order cash flow category rows in the view * Reject expense accounts without Holded identities * Order disclosed assembly ballots in their views * Order department coverage in the dashboard page builder * Order coordinator activity in the dashboard page builder * Remove redundant expense report repository ordering * Order expense review reports in the controller * Order shift signups and duration buckets in presentation * Order daily email counts in the dashboard controller * Keep program grant ordering in view models * Order expense reconciliation lists at rendering boundaries * Order Holded actual documents and managed accounts in views * Order event category and venue lists in controllers * Order email flag diagnostics in the Google controller * Order onsite roster names in the controller * Order assembly vote lists in their presentation consumers * Order Workspace accounts in the admin controller * Order visible email addresses in the profile card * Order admin legal documents in the controller * Keep preference ordering at output projections * Include attendee-only matches in audience ticket years * Order profile languages in presentation projections * Keep profile history ordering at its consumers * Keep contact-field ordering at presentation and search boundaries * Order calendar occurrences in their rendering controller * Order personal calendar commitments at output boundaries * Keep participation ordering in the GDPR export * Order machine notifications in the response controller * Reject unidentified Holded contacts and sales documents * Keep workgroup meeting ordering at its consumers * Order workgroup log entries in the timeline view * Order campaign code summaries in Tickets * Keep team role ordering at its consumers * Order unmatched Holded documents at their rendering consumers * Keep expense-account display ordering in its consumers * Move approved-event display ordering out of the cache * Order camp galleries at their rendering consumers * Order budget year lists in their views * Reuse the Google email-owner picker for account audits * Keep domain-group ordering in its consumers * Order container galleries in their shared views * Order creditor bindings at their rendering consumers * Keep ranked-ballot display ordering above the service * Keep draft-option ordering in the form mapping * Reuse one authored option sequence when counting ranked votes * Order duplicate-document previews in their view * Order survey approval queues in the controller * Order identified survey respondents in the results builder * Leave Holded chart display ordering to its consumers * Order Holded sync states and call months in the controller * Order Holded account groups and rows in the controller * Order survey result questions in their presentation consumers * Order camp role displays in their controllers * Order ticket sales buckets in report consumers * Order application history in detail controllers * Order survey choice results in presentation consumers * Share current consent version selection across snapshot consumers * Order migration reports in their presentation consumers * Order agent refusal buckets in the status view * Reuse budget year hydration for active-year reads * Save ticketing projection parameters and forecast rows atomically * Remove unused Teams repository persistence methods * Order no-show history in the profile controller * Share shift assignment notice failure handling * Reuse the detached issue lookup for mutations * Save camp member removals and role cascades atomically * Finish started account merges despite request cancellation * Save camp membership and role assignment together * Commit application approval and membership tier grants atomically * Save application and membership tier expiry corrections together * Share department identity resolution across shift metrics * Reuse complete Drive folder paths for resource lookups * Commit bulk event imports atomically * Finish ticket contact imports after request cancellation * Share post-provisioning steps in contact imports * Share survey question preparation across authoring saves * Remove unused internal mutation forwarding paths * Reject approved purchases without pending balances * Verify new invoice totals before freezing store orders * Reject malformed Stripe webhook payloads without throwing * Reject unsupported currencies in Holded document reads * Honor fractional Holded Retry-After dates * Reject incomplete TicketTailor event summaries * Require vendor validity before accepting issued tickets * Reuse the MailerLite audience snapshot for sync * Save receipt replacements and decline resets atomically * Reassign the author of moved preapproval managers * Commit grant merge revocations and reassignments together * Commit camp membership and role merges together * Commit ticket ownership and transfer merges together * Reuse the enforced Google group settings mapping * Reuse the group email for inactive resource lookup * Share Google credential parsing across input sources * Reject incomplete Cloud Translation responses * Reject missing MailerLite subscriber status * Validate MailerLite group identities before caching * Count distinct humans in MailerLite drift reports * Reuse the dietary profile mapping for updates * Consolidate Gate vendor mirror job entry points * Reassign signup actor references during account merge * Include volunteer build status in GDPR exports * Select active approval metadata for fallback membership tiers * Reuse the membership tier mapping for updates * Remove redundant service-account email cache state * Share service-account JSON loading across Google clients * Debt review: revert 3, repair 3, fix 1 ledger row Reverted: 2743fb5 Localize shared volunteer search result controls — only rendered on coordinator/admin pages; localization-admin-exempt forbids new keys there Reverted: ba09020 Reject unsupported currencies in Holded document reads — pre-empts open decision #2040 (same throw reverted before in dbb50c6: one foreign doc fails the whole sync) Reverted: 0c66eba Remove unused purchase document detail fields — HoldedWrite (#2222, now merged from main) reads Id and PaymentsTotal; the branch no longer built Repaired: 34135ac Order calendar occurrences — Calendar.md still said the service orders the merged list Repaired: a674ac8 Workgroup transitions atomic — Workgroups.md named the renamed ClosePendingRequestsAsync Repaired: ef2445f Reject expense accounts without Holded identities — Finance.md said "vendor IDs" Fixed: SHIFTS-10 — account merge now folds VolunteerBuildStatus (source-only rows move, survivor wins a collision, same rule as GeneralAvailability); row closed Fixed: dotnet format whitespace failures (code-quality job) in 19 files Review-round: 1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA6HSvWAiDr4gVc7Lff --------- Co-authored-by: Claude <noreply@anthropic.com>
The in-app notice for a new or re-consent-required legal document went to every active member while the email went only to the document's team. Both now use the team's active members. Claude-Session: https://claude.ai/code/session_0186neA4NJZtkCuc6yysafYp Co-authored-by: Claude <noreply@anthropic.com>
* Feedback: data migration that deletes every screenshot Removing Feedback drops the only index to its screenshots, so they must be deleted first. feedback.delete-screenshots lists every file under uploads/feedback on /Debug/DataMigrations and deletes the whole prefix through IFileStorage. Run it on production before the removal PR merges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA6c1saziAgfVAzPNbR * Feedback screenshot cleanup goes through IFileStorage only Status and Apply now live on FeedbackService: the report rows index the keys, IFileStorage confirms which still exist and deletes them, then the whole uploads/feedback prefix so orphans go too. No direct filesystem access and no parallel root. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA6c1saziAgfVAzPNbR --------- Co-authored-by: Claude <noreply@anthropic.com>
…2234) * Move the Consent Coordinator review queue from Onboarding to Consent The queue's verdicts (clear, flag) live in Consent's consent_reviews, so the screen now lives there too, at /Consent/ReviewQueue (old /OnboardingReview URL dropped, no redirect). Reject still goes through Onboarding's IOnboardingIntake.RejectSignupAsync, which also changes account state, teams and mail. Onboarding no longer clears or flags; it keeps the rejection record and the Pending threshold write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA4AZ7wVcJxgC1vgdJZ * Point the e2e review-queue specs and the Users slot doc at the moved queue Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA4AZ7wVcJxgC1vgdJZ * Flag fake accounts in Users; seeders stop writing Consent verdicts Users owns a "not a real person" marker (User.MarkedFakeAt, read as UserInfo.IsFake), written only by IUserWrite.MarkFakeAsync (idempotent, audited once). The gate-terminal seeder marks on every password set and the dev persona seeder on every role-persona sign-in, instead of recording a Cleared consent check through IConsentWrite. Consent's review queue skips fake accounts. Guests stay unmarked. Migration: one nullable column on users (AddUserMarkedFakeAt). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5iRoj68ARVJsdxU78 * Skip fake accounts in the shared review predicates so the pill and meters match the queue Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5iRoj68ARVJsdxU78 --------- Co-authored-by: Claude <noreply@anthropic.com>
* CI: label and comment on PRs that conflict with main Re-checks every open PR on each push to main (and a PR's own pushes), adds a merge-conflict label plus one comment so the session watching the PR wakes and merges main in, drops ready-to-merge, and removes the label once clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA427NKUHL8tCv9hvog * CI: per-PR concurrency groups so queued conflict checks aren't dropped Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA427NKUHL8tCv9hvog * CI: conflict check survives partial failures and concurrent runs Drop ready-to-merge on every conflicted run, comment before labelling so a failed comment is retried, and treat a 404 label removal as done. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA427NKUHL8tCv9hvog --------- Co-authored-by: Claude <noreply@anthropic.com>
--- updated-dependencies: - dependency-name: Markdig dependency-version: 1.5.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps AngleSharp from 1.8.6 to 1.9.0 Bumps HtmlSanitizer from 9.2.1039 to 10.0.1120 --- updated-dependencies: - dependency-name: AngleSharp dependency-version: 1.9.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: HtmlSanitizer dependency-version: 10.0.1120 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
--- updated-dependencies: - dependency-name: Google.Apis.Auth dependency-version: 1.78.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Route Finance journal postings through Holded write outcomes Advance CENTRAL-105 using the existing write contract, retaining retry tags and journal amount markers. Audit confirmation outcomes instead of connector references. Close CONSENT-1 under the standing policy against controller-policy pinning tests. * Consolidate notification delivery in the emitter Share preference filtering, copy limits and persistence between individual sends and role broadcasts while preserving their resolution scopes. Remove the redundant single-notification repository write. * Preserve consent reminder cooldowns across account merges Read the latest reminder stamp across each survivor's identity chain instead of ignoring stamps left on merged-away accounts. Keep historical rows and existing export and erasure behavior intact. * Remove obsolete single-consumer consent helpers Keep required-consent projection in its sole service owner now that the cache delegates to it. Inline the single-use chat-terms name in its document definition and retain the existing shaping assertions through the service boundary. * Report term renewal reminder failures after completing fanout Collect email and sent-stamp failures while attempting the remaining recipients, then fail the job so failed reminders can retry. Preserve best-effort in-app notices and successful reminder stamps. * Report incomplete account deletion runs as failures Attempt every due account, then propagate collected anonymization failures for job visibility and retry. Keep post-erasure confirmation delivery failures terminal and preserve their identity-safe logging. * Record suspension sweep outcomes at the job boundary Count every completed sweep once, including empty candidate sets and unchanged users. Remove run-success accounting from the domain service while retaining its per-member suspension metrics. * Reuse canonical user snapshots for notification addresses * Reuse canonical user emails throughout ticket transfers * Fail scheduled MailerLite syncs when work remains incomplete * Audit system-team membership changes before Google provisioning * Audit Holded expense-account creation before saving its registry row * Keep failed pre-approval reminders eligible for retry * Exclude internal contracts from the public interface surface report * Select relevant search hits before applying result limits * Select the strongest people-search matches before the safety cap * Report incomplete survey reminder sweeps and reuse delivery identities * Reuse renewal reminder delivery identities after failed stamps * Reuse assembly email deliveries within each announced deadline * Reuse re-consent reminder deliveries within each cooldown cycle * Audit each membership expiry within its tier mutation * Include Base interfaces in public surface reports * Consolidate camp membership decision notices * Finish lifecycle inbox updates after committed state changes * Commit deletion requests and access revocations atomically * Record failed email outbox job runs * Suspend every verified Workspace mailbox before erasure * Keep MailerLite erasure scoped to the raw account * Remove unused email projection query methods * Separate shift signup notices from state changes * Keep rideshare request answers within their event * Distinguish riders from drivers when matching ride requests * Resolve active survey audiences from account state * Derive profile setup mode from account state * Reuse survey answer context across response exports * Isolate survey translation preparation from authoring * Preserve gate admit timestamps in vendor mirror jobs * Format pending deletion dates in the UI culture * Unify feedback triage persistence and audit ordering * Move user summary display ordering to presentation * Localize coordinator membership notices by recipient language * Localize coordinator shift notices by recipient language * Resolve issue notice recipients and actors before self-exclusion * Keep saved issue notices progressing after role lookup failures * Move pending consent display ordering to rendering consumers * Continue preapproval manager fanout after individual delivery failures * Exclude historical ticket orders from shift dashboard metrics * Report assembly sweep delivery failures after completing remaining work * Persist re-consent notification batches across unchanged sync retries * Report legal sync failures after completing successful document work * Separate Rideshare interest notices from mutation rules * Match notification search text literally * Match shift tag names literally when searching and creating * Compare pending merge email addresses literally * Match legacy Google group addresses literally * Reject group links whose resolved identity is already active * Reuse the active resource type query across Google readers * Reuse resolved user snapshots for Governance email recipients * Reuse resolved user snapshots across survey email workflows * Reuse resolved user snapshots for campaign email recipients * Reuse recipient snapshots in preapproval email delivery * Reuse grant recipient snapshots while preserving email recovery * Reuse reporter snapshots for support reply emails * Reuse member snapshots for SEPA payout notices * Reuse submitter snapshots for expense approval notices * Reuse recipient snapshots for workgroup lifecycle emails * Reuse caller snapshots for composer self-send * Preserve committed deletion requests when confirmation fails * Attempt every committed consent suspension audit * Align MailerLite audience previews with canonical email selection * Isolate Teams Google Group membership calculation * Reject grouping separators in SEPA payout inputs * Reject grouping separators in workgroup budget amounts * Keep Stripe payment recovery with Store payment ingestion * Localize role assignment notices for their recipients * Attempt every committed system-team membership audit * Audit committed coordinator-role reconciliation changes * Attempt every membership audit after team deactivation * Commit camp deletion and its audit together * Commit image and container deletions with their audits * Keep best-effort audit writes outside business transactions * Audit completed workflows after business transactions commit * Audit replacement provisioning only after its outer commit * Defer preapproval effects until expense transactions commit * Debt review: revert 0, repair 2, fix 0 findings Repaired: 5e0ad14 Audit each membership expiry within its tier mutation — Governance data-access.md now says the TierDowngraded audit follows the commit (3e17a43 moved it). Repaired: b9b320a Commit deletion requests and access revocations atomically — IAccountDeletionService XML doc no longer claims the audit commits with the marker. Fixed: dotnet format whitespace violations failing the code-quality check (10 files). Review-round: 1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA51VTAAwfAjB4ssCdZ --------- Co-authored-by: Claude <noreply@anthropic.com>
* chore(deps): Bump CsvHelper from 33.1.0 to 34.0.0 --- updated-dependencies: - dependency-name: CsvHelper dependency-version: 34.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Port CSV code to CsvHelper 34 CsvHelper 34 is a rewrite: CsvConfiguration/ClassMap are gone, options are init-only records, and zero-field records are refused. HumansCsv now builds CsvReaderOptions/CsvWriterOptions with the same conventions, gains WriteBlankLine for section breaks, and the bulk-event record uses [CsvRecord]. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5kJubQyXLP8RwjZSS * About page: CsvHelper 34.0.0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5kJubQyXLP8RwjZSS --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
--- updated-dependencies: - dependency-name: Ical.Net dependency-version: 5.2.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Move the GDPR contributor seam into Base IUserDataContributor and UserDataSlice move from Humans.Gdpr/Contracts to Humans.Base/Gdpr, namespace unchanged. Every data-owning section implemented the seam, so 42 projects referenced the Gdpr section for two types; those references are dropped. Gdpr is now referenced only by Users (IGdprService), Web, and the Gdpr/Users/Web/Integration test projects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA78CpJeYKoxRTGsySg * Trim Base csproj note on the Gdpr seam to its contract Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA78CpJeYKoxRTGsySg --------- Co-authored-by: Claude <noreply@anthropic.com>
* Share one calendar event form across Calendar and Workgroups Calendar publishes ICalendarEventForm and the _CalendarEventForm partial (the workgroup layout: date + time inputs, time zone chooser, location, description, all-day and recurrence where the host supports them). CalendarEventForm.Resolve is the one conversion from posted local fields to stored times. Workgroup meetings drop their own UTC-only form for it: the zone defaults to the organisation zone (Event:TimeZoneId, now readable via ISettingsService.GetTimeZoneIdAsync), and meetings gain a Description field separate from Minutes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5AnnRepibQGTwJeEP * Render the shared form's time inputs through ToInvariantTime Inline asp-format date literals break the single-home rule (HUM0030). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5AnnRepibQGTwJeEP * Use NodaTime LocalDate/LocalTime on the shared calendar form The Shell's LocalDateTime binder now also binds LocalTime from the browser's seconds-free type="time" value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5AnnRepibQGTwJeEP * Point the recurrence picker browser test at the shared form Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5AnnRepibQGTwJeEP --------- Co-authored-by: Claude <noreply@anthropic.com>
* Move the audit append path into Base IAuditLogService (with AuditLogEntrySnapshot) and AuditActionDefinition with its contributor contract move from Humans.AuditLog/Contracts to Humans.Base/AuditLog, namespace unchanged. Projects that only wrote audit rows or declared actions drop their AuditLog reference. AuditLog is still referenced by Web, Agent (viewer), GoogleIntegration (legacy reader) and the six sections whose views render <vc:audit-log>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA78CpJeYKoxRTGsySg * Drop orphaned AuditLog reference comments in Settings Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA78CpJeYKoxRTGsySg * Point AuditLog data-access map at the Base location Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA78CpJeYKoxRTGsySg --------- Co-authored-by: Claude <noreply@anthropic.com>
* Cancel a SEPA file the bank rejected, and collapse file cards to a summary Cancel file withdraws every live transfer of a file in one save, all or nothing, audits each, and emails nobody. File cards show count and total and start collapsed once booked or cancelled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA6X9gPUU8STKsrznnB * Serialize SEPA withdrawal and file cancel with booking Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA6X9gPUU8STKsrznnB --------- Co-authored-by: Claude <noreply@anthropic.com>
* Repeat workgroup meetings and post meeting notes as log entries Meetings take a recurrence rule and zone from the shared calendar form, and Calendar's expander repeats them everywhere: the group timeline, the next meeting card, the rhythm check, the community calendar and the personal feed (one repeating VEVENT with a zoned DTSTART). Notes after a meeting are a new Meeting notes log kind, optionally linked to the meeting, posted from an Add notes button beside each started occurrence. The meeting form's Minutes box goes; existing minutes still show. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5AnnRepibQGTwJeEP * Fix whitespace formatting in feed test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5AnnRepibQGTwJeEP * Refuse sub-daily meeting rules, count only real meetings as activity, keep notes editable Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5AnnRepibQGTwJeEP * Find a meeting's next occurrence however far off Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186neA5AnnRepibQGTwJeEP --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Batched promotion of QA-tested changes from
peterdrier/Humans:mainto production.All issue/PR refs are qualified per
memory/process/issue-refs-qualified.md—peterdrier/Humans#NNNfor peter-fork PRs,nobodies-collective/Humans#NNNfor upstream issues.Commits
8041d3d1Repeat workgroup meetings and post meeting notes as log entries (Repeat workgroup meetings and post meeting notes as log entries peterdrier/Humans#2260)c34e6468Cancel a rejected SEPA file; collapsible file summaries (Cancel a rejected SEPA file; collapsible file summaries peterdrier/Humans#2263)45995149Move the audit append path into Base (Move the audit append path into Base peterdrier/Humans#2253)cc49d57aShare one calendar event form across Calendar and Workgroups (Share one calendar event form across Calendar and Workgroups peterdrier/Humans#2257)3929aea0Move the GDPR contributor seam into Base (Move the GDPR contributor seam into Base peterdrier/Humans#2252)35dcd291chore(deps): Bump Ical.Net from 5.2.3 to 5.2.4 (chore(deps): Bump Ical.Net from 5.2.3 to 5.2.4 peterdrier/Humans#2248)563a6a6bBump CsvHelper to 34.0.0 and port CSV code to its new API (Bump CsvHelper to 34.0.0 and port CSV code to its new API peterdrier/Humans#2251)8a85e6b0Daily tech-debt sweep — 2026-11-02 (Daily tech-debt sweep — 2026-11-02 peterdrier/Humans#2242)e07d30f6chore(deps): Bump Google.Apis.Auth from 1.77.0 to 1.78.0 (chore(deps): Bump Google.Apis.Auth from 1.77.0 to 1.78.0 peterdrier/Humans#2246)90725811chore(deps): Bump AngleSharp and HtmlSanitizer (chore(deps): Bump AngleSharp and HtmlSanitizer peterdrier/Humans#2247)3716ec0fchore(deps): Bump Markdig from 1.5.0 to 1.5.1 (chore(deps): Bump Markdig from 1.5.0 to 1.5.1 peterdrier/Humans#2249)1b3a8191CI: flag PRs that conflict with main (CI: flag PRs that conflict with main peterdrier/Humans#2238)3b63d660Flag fake accounts in Users; seeders stop writing Consent verdicts (Flag fake accounts in Users; seeders stop writing Consent verdicts peterdrier/Humans#2234)da739126Feedback: data migration that deletes every screenshot (Feedback: data migration that deletes every screenshot peterdrier/Humans#2237)8cdcfb85Consent: new-version notices go to the document's team only (Consent: new-version notices go to the document's team only peterdrier/Humans#2232)7a32d2c6Daily tech-debt sweep — 2026-10-31 (Daily tech-debt sweep — 2026-10-31 peterdrier/Humans#2228)e854458fStart scheduled debt runs with the latest main runner release (Run scheduled debt sweeps with the latest main runner peterdrier/Humans#2235)5db8ae24Require discovery and shared validation for nightly correction batches (Batch nightly corrections through discovery and shared validation peterdrier/Humans#2233)130aa17ddoctor(Consent): every refused signature gets a message, and a recorded one never reads as failed (doctor(Consent): every refused signature gets a message, and a recorded one never reads as failed peterdrier/Humans#2227)ed543724docs: fix stale public-facing files before they join the freshness catalog (docs: fix stale public-facing files before they join the freshness catalog peterdrier/Humans#2226)8511acd9Privacy page: list every third-party processor that receives personal data (Privacy page: list every third-party processor that receives personal data peterdrier/Humans#2225)b2eb9b94Add section-map skill: C4 component map of one section (Add section-map skill: C4 component map of one section peterdrier/Humans#2223)59207770Holded single mirror, phase 1: the IHoldedWrite face (Holded single mirror, phase 1: the IHoldedWrite face peterdrier/Humans#2222)da96ac40Holded single mirror, phase 1: mirror fields, reads and pages (Holded single mirror, phase 1: mirror fields, reads and pages peterdrier/Humans#2221)7229f48dCantina roster reveal writes one audit row, not one per member (Cantina roster reveal writes one audit row, not one per member peterdrier/Humans#2224)59dccca9docs: freshness sweep — 106 entries (upstream@f71de1eb) (docs: freshness sweep — 106 entries (upstream@f71de1eb) peterdrier/Humans#2220)DB changes
LegalDbContext(Consent):20261102063239_PersistReConsentNotificationBatches— sequencing verifiedHoldedDbContext(Holded):20261030154917_HoldedLedgerEntryIdAndChecked— sequencing verifiedUsersDbContext(Users):20261101142832_AddUserMarkedFakeAt— sequencing verifiedWorkgroupsDbContext(Workgroups):20261103113444_WorkgroupMeetingDescription,20261103134311_WorkgroupRecurringMeetingsAndNotes(apply order) — sequencing verified (end-of-chain, snapshot updated, newest Designer ≡ snapshot,has-pending-model-changesclean)All four contexts: new migrations sort after upstream's chain tip, snapshot modified,
has-pending-model-changesreports no changes.Operator note: peterdrier#2237 adds the
feedback.delete-screenshotsdata migration on/Debug/DataMigrations; per its commit it must be run on production before the Feedback-removal PR merges.Test plan
Generated by Claude Code