chore(deps): upgrade swentel/nostr-php 1.9.2 -> 1.9.4, raise floor to PHP 8.2 #2

Merged
laoc merged 1 commit from chore/nostr-php-1.9.4 into main 2026-07-30 20:58:51 +00:00
Owner

What and why

The constraint was >=1.5 <1.9.3, capped in the monorepo-split commit with no recorded reason. Two things made removing it worthwhile:

  • 1.9.3 replaces leigh/chacha20 — abandoned, no suggested replacement, composer warned on every install — with the maintained dsbaars/chacha20.
  • 1.9.4 adds a request timeout property, which we want for relay calls that hang.

The cost is PHP 8.1: 1.9.4 requires >=8.2 <8.6. PHP 8.1 is past end of life, and shipping an abandoned crypto dependency is the worse of the two risks for a redistributable plugin. Decision confirmed by laoc_buzz.

The floor is declared in four places, not one

This is the part worth reviewing. Bumping composer.json alone would have been a latent bug:

where enforced by
require.php in all five modules composer, at install
Requires PHP: in the four WP plugin headers WordPress, at activation
CLAUDE.md humans
docker-compose.yml already php8.4 — no change needed

Left at 8.1, the plugin headers would have let a site running PHP 8.1 install and activate the plugin, which then fatals at runtime on 8.2-only vendor code. That is exactly the redistribution failure this bump exists to prevent.

ExtendedFilter is unaffected

#[\AllowDynamicProperties] is still on the parent Filter in 1.9.4, so colon-named dynamic properties do not trip the PHP 8.2 dynamic-property deprecation — the one axis where this bump could have interacted with the class merged in #1.

Evidence

Full suites on 1.9.4, every module that has one:

shared          15/15   (22 assertions)
longform-nostr   5/5    ( 8 assertions)
nostr-calendar  17/17   (56 assertions)
nostr-publish   14/14   (38 assertions)

Live against wss://amb-relay.edufeed.org through NostrFetcher, byte-identical to the pre-bump run:

#ext:ekw:gradeLevel:id = <real>    ->    3
#ext:ekw:gradeLevel:id = <bogus>   ->    0   (twice)
#l = ekw                           ->   33
kinds only, no tag filter          ->  100

The bogus-value control is part of the evidence: if it matched the real count, the filter would be a no-op and both numbers meaningless.

## What and why The constraint was `>=1.5 <1.9.3`, capped in the monorepo-split commit with **no recorded reason**. Two things made removing it worthwhile: - **1.9.3 replaces `leigh/chacha20`** — abandoned, no suggested replacement, composer warned on every install — with the maintained `dsbaars/chacha20`. - **1.9.4 adds a request timeout property**, which we want for relay calls that hang. The cost is PHP 8.1: 1.9.4 requires `>=8.2 <8.6`. PHP 8.1 is past end of life, and shipping an abandoned crypto dependency is the worse of the two risks for a redistributable plugin. Decision confirmed by laoc_buzz. ## The floor is declared in four places, not one This is the part worth reviewing. Bumping `composer.json` alone would have been a latent bug: | where | enforced by | |---|---| | `require.php` in all five modules | composer, at install | | **`Requires PHP:` in the four WP plugin headers** | **WordPress, at activation** | | `CLAUDE.md` | humans | | `docker-compose.yml` | already `php8.4` — no change needed | Left at `8.1`, the plugin headers would have let a site running PHP 8.1 install and activate the plugin, which then fatals at runtime on 8.2-only vendor code. That is exactly the redistribution failure this bump exists to prevent. ## `ExtendedFilter` is unaffected `#[\AllowDynamicProperties]` is still on the parent `Filter` in 1.9.4, so colon-named dynamic properties do not trip the PHP 8.2 dynamic-property deprecation — the one axis where this bump could have interacted with the class merged in #1. ## Evidence Full suites on 1.9.4, every module that has one: ``` shared 15/15 (22 assertions) longform-nostr 5/5 ( 8 assertions) nostr-calendar 17/17 (56 assertions) nostr-publish 14/14 (38 assertions) ``` Live against `wss://amb-relay.edufeed.org` through `NostrFetcher`, byte-identical to the pre-bump run: ``` #ext:ekw:gradeLevel:id = <real> -> 3 #ext:ekw:gradeLevel:id = <bogus> -> 0 (twice) #l = ekw -> 33 kinds only, no tag filter -> 100 ``` The bogus-value control is part of the evidence: if it matched the real count, the filter would be a no-op and both numbers meaningless.
The constraint was `>=1.5 <1.9.3`, capped in the monorepo-split commit with no
recorded reason. Two things made the cap worth removing:

- 1.9.3 replaces `leigh/chacha20`, which is **abandoned with no suggested
  replacement**, with the maintained `dsbaars/chacha20`. Composer warned on
  every install.
- 1.9.4 adds a request timeout property, which the plugin wants for relay
  calls that hang.

The cost is PHP 8.1: 1.9.4 requires `>=8.2 <8.6`. PHP 8.1 reached end of life,
and shipping an abandoned crypto dependency is the worse of the two risks for a
plugin meant to be redistributable.

Raised in all four places the floor is actually declared, not just composer:

- `require.php` in all five modules
- **`Requires PHP:` in the four WordPress plugin headers** — this is the one
  WordPress itself enforces at activation. Left at 8.1 it would have let a site
  on 8.1 install the plugin and fatal at runtime, which is precisely the
  redistribution failure the bump is meant to avoid.
- the documented stack in `CLAUDE.md`

The dev container was already `wordpress:6.8-php8.4-apache`, so no change there.

`ExtendedFilter` is unaffected: `#[\AllowDynamicProperties]` is still on the
parent `Filter`, so colon-named dynamic properties do not trip the PHP 8.2
dynamic-property deprecation — the one axis where this bump could have
interacted with it.

Full suites on 1.9.4, every module that has one:

    shared          15/15   (22 assertions)
    longform-nostr   5/5    ( 8 assertions)
    nostr-calendar  17/17   (56 assertions)
    nostr-publish   14/14   (38 assertions)

And live against wss://amb-relay.edufeed.org through NostrFetcher, identical to
the pre-bump run:

    #ext:ekw:gradeLevel:id = <real>    ->    3
    #ext:ekw:gradeLevel:id = <bogus>   ->    0   (twice)
    #l = ekw                           ->   33
    kinds only, no tag filter          ->  100

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
laoc merged commit deb1902197 into main 2026-07-30 20:58:51 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
edufeed/wp-plugin-amb-nostr!2
No description provided.