Repository navigation
Conversation
Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
…#1685) * fix(identity): fold a person's duplicate candidacy when consolidating Consolidating a mistyped CPF/RF refused when both numbers sat on candidacies of the same account, because ffc_recruitment_candidate holds each identifier once, and no screen could decide about the second candidacy. The mistyped candidacy is now folded into the sound one: classifications move by candidate_id only, staging rows are re-pointed, the emptied row is deleted and the survivor gains only values it lacks. A shared notice/adjutancy/list, a different PCD condition, a conflicting other identifier or different accounts are still refused (#1682). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA * fix(identity): drop an identical, never-called duplicate classification when folding candidacies A preliminary list promoted under the mistyped number and a definitive list re-imported under the right one leave both candidacies with the same standing on one notice, adjutancy and list. Where the pair is identical (rank, score, time points, EMEBS, preview status and reason) and neither side was ever called, the merged side's copy is dropped before the move; any difference or any call still refuses. Re-measured at write time (#1682). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA * fix(identity): read candidacy-merge rows through ArrayValue for the level-9 row gate Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA --------- Co-authored-by: Claude <noreply@anthropic.com>
…1686) * fix(recruitment): the CSV import honours the RF check digit setting The import refused a mistyped CPF but never checked an RF, even with Settings -> General -> RF check digit on, while every other write path refused it through validate_rf(). The validator now calls validate_rf(), which reads the setting: off keeps today's behaviour, on refuses the row with recruitment_csv_rf_invalid and its line number (#1683). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA * test(recruitment): use the standard bad-check-digit RF fixture Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA --------- Co-authored-by: Claude <noreply@anthropic.com>
Each per-number Move / Split group on the account tiers shows the names recorded beside that number. IdentityRecordNames now also reads ffc_submissions, decoding the encrypted answers first and the plaintext copy second through SubmitterName, bounded to 20 rows per hash -- the store where the shared-mailbox panel's rows live (#1684). Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
Adds a task issue form and an area dropdown on the bug and feature forms, rewrites the PR template (stale since 6.7.3) and adds a release template, and writes the rules around them into CLAUDE.md: an issue before every PR, titles, labels, one merge at a time, closing issues by hand and what happens to branches (#1688). Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
The agent's PR tool cannot set labels at creation, so they are applied as the next step, before the PR is marked ready. Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
* chore(deps)(deps-dev): bump phpstan/phpstan from 2.2.16 to 2.3.1 Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.16 to 2.3.1. - [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits) --- updated-dependencies: - dependency-name: phpstan/phpstan dependency-version: 2.3.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * refactor(frontend): compute the asset suffix once in frontend_assets() PHPStan 2.3.1 reports `$s ?? …` in the CSV-download branch as dead (nullCoalesce.variable): $has_csv_download implies $has_base_assets, so $s is always set there. Removing only the fallback makes 2.2.16 report $s as possibly undefined, so the suffix is now computed once before the branches, which both versions accept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA --------- 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>
Bumps [eslint](https://github.com/eslint/eslint) from 10.11.0 to 10.12.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](eslint/eslint@v10.11.0...v10.12.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.12.0 dependency-type: direct:development 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> Co-authored-by: Alex Meusburger <rpgmem@gmail.com>
Bumps [jsdom](https://github.com/jsdom/jsdom) from 30.1.1 to 30.1.2. - [Release notes](https://github.com/jsdom/jsdom/releases) - [Commits](jsdom/jsdom@v30.1.1...v30.1.2) --- updated-dependencies: - dependency-name: jsdom dependency-version: 30.1.2 dependency-type: direct:development 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> Co-authored-by: Alex Meusburger <rpgmem@gmail.com>
…larations together (#1696) The repository had no LICENSE file, so GitHub showed no licence while the plugin header, readme.txt, composer.json and README.md said GPLv3 or later, and package.json declared none. LICENSE now carries the official AGPLv3 text and every declaration says AGPLv3 or later. PluginIdentityTest fails when any of them disagrees, as it already does for the version and the floors. The vendored bundles in libs/js stay MIT. Closes #1695 Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
…paths (#1697) * test(audience): cover audience, recruitment and reregistration error paths Covers the logged-in audience calendar, the audience CSV import/export handler tiers, the reregistration form inputs and admin views, the recruitment schema migration chain, booking conflict queries, the public recruitment listing filters, the "My Calls" section, the reregistration AJAX, frontend and submission-action flows, and the self-scheduling post-commit failure paths. Across the 18 target files the uncovered statements fall from 1,119 to 63; what remains is the ABSPATH guard, `exit` after redirects and two fopen() failures. Refs #1690 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA * docs(changelog): record the audience, recruitment and reregistration coverage Refs #1690 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA * docs(changelog): drop a doubled blank line Refs #1690 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA --------- Co-authored-by: Claude <noreply@anthropic.com>
…ings error paths (#1700) * test(certificates): cover certificate templates, form editor and settings error paths Covers the refusal, not-found and failure branches of the certificate template screen and receipt selector, the public operator-access metabox statuses, the form editor save handler, the Date Messages screen and its failed writes, third-party page-cache purges (isolated processes), QR temp file failures, rate-limit gates and their log rows, settings maintenance tools that throw, activity-log cursor and submission trail, the role editor, the submissions export source and the captcha tab. Measured against the develop clover, 754 of the 972 uncovered statements in the 18 targeted classes are now covered (CertTemplateAdminScreen 99->26, PublicCsvDownloadMetabox 97->3, DateMessagesAdminPage 86->5, FormCache 83->2, CertTemplateReceiptSettings 70->3, FormEditorSaveHandler 68->5, QRCodeGenerator 55->9, AdminUserCustomFields 49->3, RateLimitChecker 47->2, ActivityLogQuery 40->2, RoleCapabilityEditor 39->2, SubmissionsExportSource 39->2, SettingsActionHandler 41->15, TabCaptcha 26->6). Refs #1690 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA * docs(changelog): record the certificate, form editor and settings coverage Refs #1690 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA --------- Co-authored-by: Claude <noreply@anthropic.com>
…error paths (#1701) * test(identity): cover identity resolution, migrations and encryption error paths Drive the identity-resolution screen's nine POST handlers and its render through their seams (capability refusals, nonce keys, outcomes, redirects), and cover the refusal, empty-read, write-failure and absent-store paths of the identity normalisation, key-rotation, email-rehash, CPF/RF split and html-image migrations, the strategy calculator's lazy builds, the FK migration, the datetime-to-unix helper, role registration, profile reads and writes, user creation, legacy v1 decryption and the identity repair, relink, agreement, search and conflict queries. Measured against the develop clover, uncovered statements across the 19 target files drop from 1016 to 175 (841 newly covered); the largest gains are the resolution page (185 -> 9), identity normalisation (116 -> 15) and the status calculator (107 -> 17). Refs #1690 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA * docs(changelog): record the identity, migration and encryption coverage Refs #1690 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA --------- Co-authored-by: Claude <noreply@anthropic.com>
…y token (#1704) ci.yml, lint.yml, phpcs.yml and assets.yml declared no permissions, so their jobs ran with the repository's default GITHUB_TOKEN scope although none writes anything; the only token use is the non-blocking Coveralls upload, which passes it to identify the repository. All four now declare contents: read. Closes #1703 Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
CI measured 93.64% line coverage after the error-path test pushes of #1697, #1700 and #1701. The floor follows the rule now written in CLAUDE.md and shared by the four plugins: the highest of 90%, the measured figure minus 5 points, and its current value. Refs #1690 Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
The Reregistration menu and render_page() admitted only ffc_view_reregistration, so a custom role holding ffc_manage_reregistration alone got "Permission denied". The 3-state model says a manage grant does not also need the view one: the page now opens for view OR manage, and the menu is registered under whichever tier the user holds, as Date Messages already does. Closes #1698 Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
… magic-link QR (#1707) MagicLinkHelper::generate_magic_link() returns an empty string only for an empty token, and generate_magic_link_qr() already returns early when the submission has none, so the "Link generation failed" branch could never run. No behaviour change for a submission with or without a token. Closes #1702 Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
Functions\expect( 'x' )->never() is never consulted when setUp() already stubbed x with Functions\when(): the stub keeps answering, so the test passed whether or not x ran. A direct call injected after each of the twelve such sites left every test green; the same injection now fails every one of them. The sites count calls through a new Tests\Support\CallLog helper (a second when() does replace the first) and assert the count after the act. RestControllerTest had been hiding a call: the constructor registers a filter through add_filter(), so its count now starts after the constructor. ExpectAfterSetUpStubTest refuses the shape, and CLAUDE.md records how to assert a call count when setUp() stubs the function. Closes #1699 Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
Bumps the three version sites to 6.38.0, renames [Unreleased] to [6.38.0] (2026-10-12) with a condensed section that still cites every delivering issue, and rewrites the Upgrade Notice for this release, which carries the AGPLv3 licence change. The batch's @SInCE tags already name 6.38.0, and the documentation topics for the two operator-facing changes (#1683, #1684) were updated in their PRs. Claude-Session: https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA Co-authored-by: Claude <noreply@anthropic.com>
rpgmem
marked this pull request as ready for review
October 12, 2026 23:06
rpgmem
enabled auto-merge (squash)
October 12, 2026 23:06
rpgmem
disabled auto-merge
October 12, 2026 23:07
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.
Release 6.38.0
The licence moves to AGPLv3 or later. Identity resolution names each number in "One address, several people" and can consolidate a candidate imported twice. The recruitment CSV import honours the RF check digit, and a manage-only role reaches the Reregistration screen. Tests now cover error paths across the plugin, and the PHP coverage floor rises to 90%. CI jobs run with a read-only token. Issues: #1682, #1683, #1684, #1690, #1695, #1698, #1699, #1702, #1703.
Checklist
ffcertificate.phpheader,FFC_VERSION,readme.txtStable tag)[Unreleased]renamed to[6.38.0] (2026-10-12), fresh empty[Unreleased]above, section condensed by storyreadme.txt== Upgrade Notice ==rewritten for this version, ≤300 characters@sincetags written mid-batch corrected to6.38.0(already correct)Added/Changedbullet (Recruitment CSV import ignores the RF check digit setting #1683 and Identity resolution: name each number on "One address, several people" #1684 updated their topics; the rest change no operator-facing screen)After merge (maintainer / agent)
CLAUDE.md.developtomain(--force-with-lease).🤖 Generated with Claude Code
https://claude.ai/code/session_018srx5hc431EYmG4MHUr2KA
Generated by Claude Code