Repository navigation
1.9.79: the adversarial findings on the re-click review round and the 1.9.78 findings round - #282
Conversation
… 1.9.78 findings round The non-blocking adversarial findings on #258 and #262, by number: #258 - 1: the re-click backfill steps a click over only for its own errors. A lock wait, deadlock, timeout, lost connection or a full or read-only server (ReClickBackfill::MOMENT_ERRNOS, and every client error) stops the run at the click and counts in none, however long it lasts. - 2: SchemaVersion compares versions with version_compare(). Only a schema older than the code names the upgrade; files older than their database answer as before, and the sync worker says to deploy the newer files. #262 - 1: the user-agent parse and the bot-range verdict, kept 30 days, are keyed by the code's version too. CacheKeyNamespaceTest lists every key on the bare install hash with why. - 2: the landing script reads p202_consent as PHP's $_GET files it (p202.consent, p202_consent[] and the rest), with PHP's trim(), and a followed tracker link keeps no spelling of it but the refusal. - 3: the approval page's words are checked as rendered, in the account-pages browser pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U3VVstdYdz5zwv5MUbkDjT
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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee9391a426
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…as PHP does PHP's $_GET cuts a query name at its first NUL before it reads any brackets, so p202_consent%00x=0 and p202_consent%00[]=0 are a refusal to the tracker; the landing script kept the NUL and read them as absent, which is consent (found by review). p202PhpName() now cuts there first. Held to parse_str() on 45 spellings, nine of them with a NUL: the reader before this differed on seven. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U3VVstdYdz5zwv5MUbkDjT
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c74b387ce3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…e upgrade The ladder writes 1.9.30b and accepts 1.9.30a, and the version check taken in the previous round read only dotted numbers as a version, so an install at either rung lost the upgrade's 503 in the deploy window (found by review). One trailing letter is a version now; version_compare() orders both before 1.9.30. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U3VVstdYdz5zwv5MUbkDjT
…start IPN branch
GET /users/{id}/preferences now serves every integration secret as its
stored state (#270), and the PayKickstart IPN keys are one more:
paykickstart_ipn_secret_keys is on ServedPreferences::SECRET, answered
{"stored": true}, and the count this branch served in its place
(paykickstart_ipn_keys_stored, PayKickstartKeys::withoutKeys()) is gone.
GET /system/integrations keys_stored still says how many. The
PreferenceSecretsAreNotServedIntegrationTest round trip stores the keys
with the other secrets.
Conflicts: changelogs (1.9.79's lines, then this branch's), the
preferences docs and the OpenAPI schemas (1.9.79's, with the keys added
as a StoredSecret), and the controller (1.9.79's).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VRoS2SViuxaucFaKWsFnLr
…JVZoo branch #268 now dates a notification's row by the provider's own time, held to the click for a sale and to the sale for a refund, and brings 1.9.79's #270 (ServedPreferences: GET preferences serves each secret as {"stored": ...}), #280, #281 and #282. Conflicts: both changelogs keep the base's lines with the JVZoo line after them; the OpenAPI preferences update takes #270's oneOf shape, with the JVZoo key's rule in its string branch; the eval cases keep #268's admin-005 notes and add admin-006 after it. jvzoo_ipn_secret_key is already on ServedPreferences::SECRET, and JVZoo adds no other column. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRoS2SViuxaucFaKWsFnLr
…79's #270, #280, #281, #282) into the ClickBank branch Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VRoS2SViuxaucFaKWsFnLr # Conflicts: # 202-config/changelogs.json # changelogs.txt
The non-blocking findings of the adversarial reviews of #258 (4) and #262 (3), named by number. The reports stay encrypted. The review-gate change, #275, is still the last PR of 1.9.79.
What changes
#258
ReClickBackfill::MOMENT_ERRNOS, plus every client error, 2000 to 2999).failed_runsnow counts the runs that failed with the click's own error. The API doc, the OpenAPI spec, the upgrade guide and the progress note say so.SchemaVersioncompares versions withversion_compare(). Only a schema older than the code names the upgrade.upgrade.php._upgrade_query()answersfalsefor a non-transient failure, so the comparison does match. If thatCREATEfails, the 1.9.79 rung creates the same table through_upgrade_measurement_tables()and leaves the version at 1.9.78 when it cannot, so the failure stays loud and the upgrade is retried. The log line only names the cause at the 1.9.5 rung.upgrade-equals-install, MySQL 8.0 and the agent evals ran on this PR, as on 1.9.79: the review findings of the re-click restore and the ledger lock #258, and are green (below).p202 system dataenginerenders the answer as it comes (render(data)), so the new fields print with no CLI change. That was read, not run.UpgradePendingAnswerServedIntegrationTestserves.#262
LookupRepositoryFactory::cacheNamespace()): the user-agent parse and the bot-range verdict.CacheKeyNamespaceTest:p202_consentas PHP's$_GETfiles it.p202.consent=0,p202 consent=0,p202[consent=0andp202_consent[]=0were a refusal to the tracker and consent to the script.trim()characters only. A no-break space before the 1 is now a refusal in both.tests/live/autocron-switch.shdrives that handler over HTTP.Found by Codex on this PR, fixed here
p202_consent%00x=0was a refusal to the tracker and consent to the script (c74b387). The reader now cuts there first.1.9.30aand1.9.30b, which the ladder writes, so an install at either rung lost the 503 (85b9c51). One trailing letter is a version now.Also
Testing
Run locally on PHP 8.3.6 and MariaDB 10.11, with a full
vendor/.Ladder (
verify.sh --changed):tracking202/static/landing.phpwent from 391 phpcs errors to 376.Integration.
tests/run-integration-suites.shon the first commit: 145 suites, 1,412 tests, all passed, each on its own fresh database. On their own, on the current head:ReClickBackfillIntegrationTest14/14. The new case runs a lock wait, a lost connection and a statement timeout (each raised with its errno from a trigger) for two hours of runs, and nothing is stepped over. Then the tenth error of the click's own steps it over.SchemaVersionIntegrationTest9/9, covering 1.9.78, 1.9.8 (older, though greater as text), 1.9.30a and 1.9.30b, current, 1.9.80, 1.9.100 (newer, though smaller as text), not a version, and none.UpgradePendingAnswerServedIntegrationTest9/9. A schema newer than the code now answers the plain 500 over HTTP.The consent reader was held to PHP's
parse_str()on 45 spellings: arrays, dots, spaces, unmatched brackets, repeats in both orders, no-break space,\v, NUL in a value and in a name, a different case and a longer name. All 45 agree, taken from the shipped file.Browser passes, on a 1.9.79 instance served from this tree:
identity-landing64/64, with thirteen refusal spellings, seven consent spellings and the followed-link scenario. One earlier run lost one scenario to a page load interrupted seconds after the server started; it did not recur.account-pagesscenario 5/5.account-pagesrun failed 63 checks; none is this change's. Each page's "no JavaScript errors" check failed on Google's hosted ad loader, which this sandbox's network answers with an HTML redirect. Users' empty-list check failed because this instance kept a user from an earlier pass.my.tracking202.compointed at 127.0.0.1, with the server started without the proxy. Both were put back.Every fix was planted against and fails by name:
On this PR, CI on 85b9c51 is green:
integrationon MySQL 8.0,upgrade-equals-install,agent-evals,test,lint, PHPStan and the rest.🤖 Generated with Claude Code
https://claude.ai/code/session_01U3VVstdYdz5zwv5MUbkDjT